diff options
| author | Cara Salter <cara@devcara.com> | 2022-06-09 10:28:42 -0400 | 
|---|---|---|
| committer | Cara Salter <cara@devcara.com> | 2022-06-09 10:28:42 -0400 | 
| commit | 276255f5a20fa05a005e765287239ca5ffe439e4 (patch) | |
| tree | 67e325727fe49004d54deee702fb556a7d5ce1f1 /src | |
| parent | bb545403fed8af5b746778c3336a4f3a371148d6 (diff) | |
| download | solard-276255f5a20fa05a005e765287239ca5ffe439e4.tar.gz solard-276255f5a20fa05a005e765287239ca5ffe439e4.zip | |
planets: State manipulation
Diffstat (limited to 'src')
| -rw-r--r-- | src/errors.rs | 10 | ||||
| -rw-r--r-- | src/handlers/planets.rs | 52 | ||||
| -rw-r--r-- | src/main.rs | 13 | 
3 files changed, 71 insertions, 4 deletions
| 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)?) +} | 
