From 6b6f4b4779c66e73c179d2f7dbb1a0c2031c690e Mon Sep 17 00:00:00 2001 From: Martin Berg Alstad Date: Mon, 17 Jun 2024 00:21:18 +0200 Subject: [PATCH] Table endpoint for generating a truth table from a string expression --- http/simplify.http | 10 ++++++++++ src/expressions/truth_table.rs | 7 +------ src/routing/mod.rs | 5 +++-- src/routing/options.rs | 34 ++++++++++++++++++++++++++++++++ src/routing/response.rs | 15 +++++++++++++- src/routing/routes/simplify.rs | 36 ++++------------------------------ src/routing/routes/table.rs | 26 +++++++++++++++++------- 7 files changed, 85 insertions(+), 48 deletions(-) create mode 100644 src/routing/options.rs diff --git a/http/simplify.http b/http/simplify.http index 956046f..805a7b0 100644 --- a/http/simplify.http +++ b/http/simplify.http @@ -131,3 +131,13 @@ GET {{url}}/simplify/{{expression}} ### GET with simplify="true" GET {{url}}/simplify/A?simplify=true&hide=NONE&sort=DEFAULT&caseSensitive=false&hideIntermediate=false + +### GET only table + +GET {{url}}/table/A + +> {% + client.test("Response body contains only the truth table", () => { + client.assert(response.body.truthTable, "Response body does not contain the truth table") + }); +%} diff --git a/src/expressions/truth_table.rs b/src/expressions/truth_table.rs index 5f49bb7..8e90f4a 100644 --- a/src/expressions/truth_table.rs +++ b/src/expressions/truth_table.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::expressions::expression::Expression; use crate::map; +use crate::routing::options::TruthTableOptions; use crate::utils::array::Distinct; type TruthMatrix = Vec>; @@ -34,12 +35,6 @@ pub enum Sort { FalseFirst, } -#[derive(Debug, Default, Deserialize)] -pub struct TruthTableOptions { - pub sort: Sort, - pub hide: Hide, -} - impl TruthTable { pub fn new(expression: &Expression, options: TruthTableOptions) -> Self { let header = Self::extract_header(expression); diff --git a/src/routing/mod.rs b/src/routing/mod.rs index 0d75636..c9223aa 100644 --- a/src/routing/mod.rs +++ b/src/routing/mod.rs @@ -1,3 +1,4 @@ pub(crate) mod response; -mod error; -pub(crate) mod routes; \ No newline at end of file +pub(crate) mod error; +pub(crate) mod routes; +pub(crate) mod options; \ No newline at end of file diff --git a/src/routing/options.rs b/src/routing/options.rs new file mode 100644 index 0000000..d068cdb --- /dev/null +++ b/src/routing/options.rs @@ -0,0 +1,34 @@ +use serde::Deserialize; +use crate::expressions::truth_table::{Hide, Sort}; +use crate::utils::serialize::{ret_true, deserialize_bool}; + +#[derive(Deserialize)] +pub struct SimplifyOptions { + #[serde( + default = "ret_true", + deserialize_with = "deserialize_bool" + )] + pub simplify: bool, + #[serde(default = "ret_true")] + pub case_sensitive: bool, // TODO: Implement case sensitivity +} + +#[derive(Deserialize, Default)] +#[serde(rename_all = "camelCase")] +pub struct TruthTableOptions { + #[serde(default)] + pub sort: Sort, + #[serde(default)] + pub hide: Hide, + #[serde(default)] + pub hide_intermediate_steps: bool, // TODO: Implement hide intermediate steps +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimplifyAndTableOptions { + #[serde(flatten)] + pub simplify_options: SimplifyOptions, + #[serde(flatten)] + pub table_options: TruthTableOptions, +} diff --git a/src/routing/response.rs b/src/routing/response.rs index e8269b6..430c6c1 100644 --- a/src/routing/response.rs +++ b/src/routing/response.rs @@ -1,6 +1,6 @@ use axum::Json; use axum::response::{IntoResponse, Response}; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use crate::expressions::expression::Expression; use crate::expressions::simplify::Law; @@ -56,6 +56,7 @@ pub struct SimplifyResponse { pub truth_table: Option, } +// TODO derive macro impl IntoResponse for SimplifyResponse { fn into_response(self) -> Response { BaseResponse::create(self) @@ -72,4 +73,16 @@ impl IntoResponse for IsLegalResponse { fn into_response(self) -> Response { BaseResponse::create(self) } +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct TruthTableResponse { + pub truth_table: TruthTable, +} + +impl IntoResponse for TruthTableResponse { + fn into_response(self) -> Response { + BaseResponse::create(self) + } } \ No newline at end of file diff --git a/src/routing/routes/simplify.rs b/src/routing/routes/simplify.rs index 507977e..2dcb837 100644 --- a/src/routing/routes/simplify.rs +++ b/src/routing/routes/simplify.rs @@ -2,13 +2,12 @@ use axum::{Router, routing::get}; use axum::extract::{Path, Query}; use axum::http::StatusCode; use axum::response::{IntoResponse, Response}; -use serde::{Deserialize}; use crate::expressions::expression::Expression; -use crate::expressions::truth_table::{Hide, Sort, TruthTable, TruthTableOptions}; +use crate::expressions::truth_table::TruthTable; use crate::routing::error::{Error, ErrorKind}; +use crate::routing::options::{SimplifyAndTableOptions, SimplifyOptions}; use crate::routing::response::SimplifyResponse; -use crate::utils::serialize::{ret_true, deserialize_bool}; pub fn router() -> Router<()> { Router::new() @@ -19,17 +18,6 @@ pub fn router() -> Router<()> { ) } -#[derive(Deserialize)] -struct SimplifyOptions { - #[serde( - default = "ret_true", - deserialize_with = "deserialize_bool" - )] - simplify: bool, - #[serde(default = "ret_true")] - case_sensitive: bool, // TODO: Implement case sensitivity -} - async fn simplify(Path(path): Path, Query(query): Query) -> Response { match Expression::try_from(path.as_str()) { Ok(mut expression) => { @@ -52,20 +40,7 @@ async fn simplify(Path(path): Path, Query(query): Query } } -#[derive(Deserialize)] -#[serde(rename_all = "camelCase")] -struct SimplifyAndTableQuery { - #[serde(flatten)] - simplify_options: SimplifyOptions, - #[serde(default)] - sort: Sort, - #[serde(default)] - hide: Hide, - #[serde(default)] - hide_intermediate_steps: bool, // TODO -} - -async fn simplify_and_table(Path(path): Path, Query(query): Query) -> Response { +async fn simplify_and_table(Path(path): Path, Query(query): Query) -> Response { match Expression::try_from(path.as_str()) { Ok(mut expression) => { let before = expression.to_string(); @@ -73,10 +48,7 @@ async fn simplify_and_table(Path(path): Path, Query(query): Query Router<()> { Router::new() .nest("/table", Router::new() - .route("/", post(table)), + .route("/:exp", get(table)), ) } -// TODO Json Deserialize not working on Axum? Manually parse the body? -async fn table(body: Body) -> Response { - unimplemented!() +// TODO Expression as input in body +async fn table(Path(value): Path, Query(query): Query) -> Response { + match Expression::try_from(value) { + Ok(expression) => { + TruthTableResponse { truth_table: TruthTable::new(&expression, query) }.into_response() + } + Err(e) => (StatusCode::BAD_REQUEST, Error::new(e.to_string(), ErrorKind::InvalidExpression)).into_response(), + } }