about summary refs log tree commit diff stats
path: root/crates/rocie-server/src/api/get/product.rs
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-12-09 13:07:14 +0100
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-12-09 13:07:14 +0100
commitc91dce4f77ae12453203f0a28b91efb6533cc095 (patch)
tree4f50e755dff7f717d45309b08f9fe2c8c87f88bd /crates/rocie-server/src/api/get/product.rs
parentchore(rocie-client): Regenerate (diff)
downloadserver-c91dce4f77ae12453203f0a28b91efb6533cc095.zip
feat(rocie-server): Implement basic user handling and authentication
Diffstat (limited to 'crates/rocie-server/src/api/get/product.rs')
-rw-r--r--crates/rocie-server/src/api/get/product.rs237
1 files changed, 0 insertions, 237 deletions
diff --git a/crates/rocie-server/src/api/get/product.rs b/crates/rocie-server/src/api/get/product.rs
deleted file mode 100644
index 4216f9b..0000000
--- a/crates/rocie-server/src/api/get/product.rs
+++ /dev/null
@@ -1,237 +0,0 @@
-use actix_web::{HttpRequest, HttpResponse, Responder, Result, get, web};
-use log::info;
-use percent_encoding::percent_decode_str;
-
-use crate::{
-    app::App,
-    storage::sql::{
-        product::{Product, ProductId, ProductIdStub},
-        product_amount::ProductAmount,
-        product_parent::{ProductParent, ProductParentId, ProductParentIdStub},
-    },
-};
-
-/// A String, that is not url-decoded on parse.
-struct UrlEncodedString(String);
-
-impl UrlEncodedString {
-    /// Percent de-encode a given string
-    fn percent_decode(&self) -> Result<String, std::str::Utf8Error> {
-        percent_decode_str(self.0.replace('+', "%20").as_str())
-            .decode_utf8()
-            .map(|s| s.to_string())
-            .inspect(|s| info!("Decoded `{}` as `{s}`", self.0))
-    }
-
-    fn from_str(inner: &str) -> Self {
-        Self(inner.to_owned())
-    }
-}
-
-/// Get Product by id
-#[utoipa::path(
-    responses(
-        (status = OK, description = "Product found from database", body = Product),
-        (status = NOT_FOUND, description = "Product not found in database"),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-    params(
-        ("id" = ProductId, description = "Product id" ),
-    )
-)]
-#[get("/product/by-id/{id}")]
-pub(crate) async fn product_by_id(
-    app: web::Data<App>,
-    id: web::Path<ProductIdStub>,
-) -> Result<impl Responder> {
-    let id = id.into_inner();
-
-    match Product::from_id(&app, id.into()).await? {
-        Some(product) => Ok(HttpResponse::Ok().json(product)),
-        None => Ok(HttpResponse::NotFound().finish()),
-    }
-}
-
-/// Get Product by name
-#[utoipa::path(
-    responses(
-        (status = OK, description = "Product found from database", body = Product),
-        (status = NOT_FOUND, description = "Product not found in database"),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-    params(
-        ("name" = String, description = "Name of the product" ),
-    )
-)]
-#[get("/product/by-name/{name}")]
-pub(crate) async fn product_by_name(
-    app: web::Data<App>,
-    req: HttpRequest,
-    name: web::Path<String>,
-) -> Result<impl Responder> {
-    drop(name);
-
-    let name = UrlEncodedString::from_str(
-        req.path()
-            .strip_prefix("/product/by-name/")
-            .expect("Will always exists"),
-    );
-    let name = name.percent_decode()?;
-
-    match Product::from_name(&app, name).await? {
-        Some(product) => Ok(HttpResponse::Ok().json(product)),
-        None => Ok(HttpResponse::NotFound().finish()),
-    }
-}
-
-/// Get Product suggestion by name
-#[utoipa::path(
-    responses(
-        (status = OK, description = "Product suggestions found from database", body = Vec<Product>),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-    params(
-        ("name" = String, description = "Partial name of a product" ),
-    )
-)]
-#[get("/product/by-part-name/{name}")]
-pub(crate) async fn product_suggestion_by_name(
-    app: web::Data<App>,
-    req: HttpRequest,
-    name: web::Path<String>,
-) -> Result<impl Responder> {
-    drop(name);
-
-    let name = UrlEncodedString::from_str(
-        req.path()
-            .strip_prefix("/product/by-part-name/")
-            .expect("Will always exists"),
-    );
-    let name = &name.percent_decode()?;
-
-    let all = Product::get_all(&app).await?;
-
-    let matching = all
-        .into_iter()
-        .filter(|product| product.name.starts_with(name.as_str()))
-        .collect::<Vec<_>>();
-
-    Ok(HttpResponse::Ok().json(matching))
-}
-
-/// Return all registered products
-#[utoipa::path(
-    responses(
-        (status = OK, description = "All products found", body = Vec<Product>),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-)]
-#[get("/products_registered/")]
-pub(crate) async fn products_registered(app: web::Data<App>) -> Result<impl Responder> {
-    let all = Product::get_all(&app).await?;
-
-    Ok(HttpResponse::Ok().json(all))
-}
-
-/// Return all products, which non-null amount in storage
-#[utoipa::path(
-    responses(
-        (status = OK, description = "All products found", body = Vec<Product>),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-)]
-#[get("/products_in_storage/")]
-pub(crate) async fn products_in_storage(app: web::Data<App>) -> Result<impl Responder> {
-    let all = Product::get_all(&app).await?;
-
-    let mut output_products = Vec::with_capacity(all.len());
-    for product in all {
-        let amount = ProductAmount::from_id(&app, product.id).await?;
-
-        if amount.is_some_and(|amount| amount.amount.value > 0) {
-            output_products.push(product);
-        }
-    }
-
-    Ok(HttpResponse::Ok().json(output_products))
-}
-
-/// Get Products by it's product parent id
-///
-/// This will also return all products below this product parent id
-#[utoipa::path(
-    responses(
-        (status = OK, description = "Products found from database", body = Vec<Product>),
-        (status = NOT_FOUND, description = "Product parent id not found in database"),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-    params(
-        ("id" = ProductParentId, description = "Product parent id" ),
-    )
-)]
-#[get("/product/by-product-parent-id-indirect/{id}")]
-pub(crate) async fn products_by_product_parent_id_indirect(
-    app: web::Data<App>,
-    id: web::Path<ProductParentIdStub>,
-) -> Result<impl Responder> {
-    let id = id.into_inner();
-
-    if let Some(parent) = ProductParent::from_id(&app, id.into()).await? {
-        async fn collect_products(app: &App, parent: ProductParent) -> Result<Vec<Product>> {
-            let mut all = Product::get_all(app)
-                .await?
-                .into_iter()
-                .filter(|prod| prod.parent.is_some_and(|val| val == parent.id))
-                .collect::<Vec<_>>();
-
-            if let Some(child) = ProductParent::get_all(app)
-                .await?
-                .into_iter()
-                .find(|pp| pp.parent.is_some_and(|id| id == parent.id))
-            {
-                all.extend(Box::pin(collect_products(app, child)).await?);
-            }
-
-            Ok(all)
-        }
-
-        let all = collect_products(&app, parent).await?;
-
-        Ok(HttpResponse::Ok().json(all))
-    } else {
-        Ok(HttpResponse::NotFound().finish())
-    }
-}
-
-/// Get Products by it's product parent id
-///
-/// This will only return products directly associated with this product parent id
-#[utoipa::path(
-    responses(
-        (status = OK, description = "Products found from database", body = Vec<Product>),
-        (status = NOT_FOUND, description = "Product parent id not found in database"),
-        (status = INTERNAL_SERVER_ERROR, description = "Server encountered error", body = String)
-    ),
-    params(
-        ("id" = ProductParentId, description = "Product parent id" ),
-    )
-)]
-#[get("/product/by-product-parent-id-direct/{id}")]
-pub(crate) async fn products_by_product_parent_id_direct(
-    app: web::Data<App>,
-    id: web::Path<ProductParentIdStub>,
-) -> Result<impl Responder> {
-    let id = id.into_inner();
-
-    if let Some(parent) = ProductParent::from_id(&app, id.into()).await? {
-        let all = Product::get_all(&app)
-            .await?
-            .into_iter()
-            .filter(|prod| prod.parent.is_some_and(|val| val == parent.id))
-            .collect::<Vec<_>>();
-
-        Ok(HttpResponse::Ok().json(all))
-    } else {
-        Ok(HttpResponse::NotFound().finish())
-    }
-}