aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCara Salter <cara@devcara.com>2022-06-09 10:28:42 -0400
committerCara Salter <cara@devcara.com>2022-06-09 10:28:42 -0400
commit276255f5a20fa05a005e765287239ca5ffe439e4 (patch)
tree67e325727fe49004d54deee702fb556a7d5ce1f1
parentbb545403fed8af5b746778c3336a4f3a371148d6 (diff)
downloadsolard-276255f5a20fa05a005e765287239ca5ffe439e4.tar.gz
solard-276255f5a20fa05a005e765287239ca5ffe439e4.zip
planets: State manipulation
-rw-r--r--Cargo.lock4
-rw-r--r--src/errors.rs10
-rw-r--r--src/handlers/planets.rs52
-rw-r--r--src/main.rs13
4 files changed, 73 insertions, 6 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 5397925..b7b1e17 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -862,8 +862,8 @@ dependencies = [
[[package]]
name = "solarlib"
-version = "1.3.0"
-source = "git+https://git.carathe.dev/muirrum/solarlib?branch=master#d674951ce8cb5b41afe68bbeefcd9ee585125ab9"
+version = "1.4.0"
+source = "git+https://git.carathe.dev/muirrum/solarlib?branch=master#137ec4c34aa962b11148cfad443a4c88035e3d87"
dependencies = [
"mac_address",
"rand",
diff --git a/src/errors.rs b/src/errors.rs
index d76db92..b22932f 100644
--- a/src/errors.rs
+++ b/src/errors.rs
@@ -12,6 +12,9 @@ pub enum ServiceError {
#[error("Axum error: {0}")]
Axum(#[from] axum::Error),
+
+ #[error("Not Found")]
+ NotFound,
}
pub type StringResult<T = &'static str> = std::result::Result<T, ServiceError>;
@@ -23,8 +26,13 @@ impl IntoResponse for ServiceError {
fn into_response(self) -> Response {
let body = body::boxed(body::Full::from(self.to_string()));
+
+ let status = match self {
+ ServiceError::NotFound => StatusCode::NOT_FOUND,
+ _ => StatusCode::INTERNAL_SERVER_ERROR,
+ };
Response::builder()
- .status(StatusCode::INTERNAL_SERVER_ERROR)
+ .status(status)
.body(body)
.unwrap()
}
diff --git a/src/handlers/planets.rs b/src/handlers/planets.rs
index e80e7fe..a57f605 100644
--- a/src/handlers/planets.rs
+++ b/src/handlers/planets.rs
@@ -1,11 +1,11 @@
-use axum::{response::IntoResponse, Json};
+use axum::{response::IntoResponse, Json, extract::Path};
use tracing::{error, instrument};
use solarlib::star::Star;
use solarlib::planet::Planet;
-use crate::errors::*;
+use crate::{errors::*, get_star};
pub async fn list() -> JsonResult<Json<Vec<Planet>>> {
let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
@@ -16,3 +16,51 @@ pub async fn list() -> JsonResult<Json<Vec<Planet>>> {
Ok(Json(inhabitants))
}
+pub async fn get(Path(uuid): Path<String>) -> JsonResult<Json<Planet>> {
+
+ let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
+ let mut star = Star::new(con_url)?;
+
+ if let Ok(p) = star.find_planet(uuid) {
+ return Ok(Json(p));
+ } else {
+ return Err(ServiceError::NotFound);
+ }
+}
+
+pub async fn shutdown(Path(uuid): Path<String>) -> NoneResult {
+ let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
+ let mut star = Star::new(con_url)?;
+
+ if let Ok(p) = star.find_planet(uuid) {
+ p.shutdown()?;
+ } else {
+ return Err(ServiceError::NotFound);
+ }
+
+ Ok(())
+}
+
+pub async fn start(Path(uuid): Path<String>) -> NoneResult {
+ let mut s = get_star()?;
+
+ if let Ok(p) = s.find_planet(uuid) {
+ p.start()?;
+ } else {
+ return Err(ServiceError::NotFound);
+ }
+
+ Ok(())
+}
+
+pub async fn pause(Path(uuid): Path<String>) -> NoneResult {
+ let mut s = get_star()?;
+
+ if let Ok(p) = s.find_planet(uuid) {
+ p.pause()?;
+ } else {
+ return Err(ServiceError::NotFound);
+ }
+
+ Ok(())
+}
diff --git a/src/main.rs b/src/main.rs
index 8fbd0ff..742113e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,11 +2,12 @@ use axum::{
error_handling::HandleErrorLayer,
http::StatusCode,
response::IntoResponse,
- routing::get,
+ routing::{get, post},
Json, Router
};
use serde::{Deserialize, Serialize};
+use solarlib::star::Star;
use std::{net::SocketAddr, time::Duration, str::FromStr};
use tower::{BoxError, ServiceBuilder};
@@ -33,6 +34,10 @@ async fn main() {
let app = Router::new()
.route("/health", get(health_check))
.route("/planets/list", get(handlers::planets::list))
+ .route("/planets/:uuid", get(handlers::planets::get))
+ .route("/planets/:uuid/shutdown", post(handlers::planets::shutdown))
+ .route("/planets/:uuid/start", post(handlers::planets::start))
+ .route("/planets/:uuid/pause", post(handlers::planets::pause))
.layer( ServiceBuilder::new()
.layer(HandleErrorLayer::new(|error: BoxError| async move {
if error.is::<tower::timeout::error::Elapsed>() {
@@ -61,3 +66,9 @@ async fn main() {
async fn health_check() -> &'static str {
"OK"
}
+
+fn get_star() -> Result<Star, errors::ServiceError> {
+ let con_url = std::env::var("QEMU_URL").unwrap_or("qemu:///system".to_string());
+
+ Ok(Star::new(con_url)?)
+}