Browse Source

WIP: basic API

develop
chodak166 4 months ago
parent
commit
a5489495f4
  1. 2
      apps/app_api/src/api.rs
  2. 119
      apps/app_api/src/api/major_pl.rs
  3. 15
      apps/app_api/src/container.rs

2
apps/app_api/src/api.rs

@ -4,9 +4,11 @@ use std::sync::Arc;
pub mod dictionary; pub mod dictionary;
pub mod health; pub mod health;
pub mod major_pl;
pub fn routes() -> Router<Arc<AppState>> { pub fn routes() -> Router<Arc<AppState>> {
Router::new() Router::new()
.nest("/api", health::routes()) .nest("/api", health::routes())
.nest("/api", dictionary::routes()) .nest("/api", dictionary::routes())
.nest("/api", major_pl::routes())
} }

119
apps/app_api/src/api/major_pl.rs

@ -0,0 +1,119 @@
use axum::{
Json, Router,
extract::{Path, Query, State},
http::StatusCode,
response::IntoResponse,
routing::get,
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::state::AppState;
#[derive(Debug, Deserialize)]
pub struct EncodeQuery {
pub dict: Option<String>,
}
#[derive(Debug, Deserialize)]
pub struct DecodeQuery {
pub dict: Option<String>,
}
#[derive(Debug, Serialize)]
pub struct EncodeResponse {
pub input: String,
pub dict: String,
pub result: Vec<Vec<EncodePart>>,
}
#[derive(Debug, Serialize)]
pub struct EncodePart {
pub value: u64,
pub words: Vec<String>,
}
#[derive(Debug, Serialize)]
pub struct DecodeResponse {
pub input: String,
pub result: String,
}
#[derive(Debug, Serialize)]
pub struct ErrorResponse {
pub error: String,
}
impl IntoResponse for ErrorResponse {
fn into_response(self) -> axum::response::Response {
(StatusCode::INTERNAL_SERVER_ERROR, Json(self)).into_response()
}
}
impl From<anyhow::Error> for ErrorResponse {
fn from(err: anyhow::Error) -> Self {
Self {
error: err.to_string(),
}
}
}
pub async fn encode_handler(
State(state): State<Arc<AppState>>,
Path(input): Path<String>,
Query(params): Query<EncodeQuery>,
) -> Result<Json<EncodeResponse>, ErrorResponse> {
let dict_name = params.dict.unwrap_or_else(|| "demo_pl".to_string());
let encoder = state
.container
.create_encoder(&dict_name)
.await
.map_err(|e| anyhow::anyhow!("Failed to create encoder: {}", e))?;
let result = encoder
.encode(&input)
.map_err(|e| anyhow::anyhow!("Failed to encode: {}", e))?;
let encoded_parts: Vec<Vec<EncodePart>> = result
.iter()
.map(|split| {
split
.iter()
.map(|part| EncodePart {
value: part.value,
words: part.words.clone(),
})
.collect()
})
.collect();
Ok(Json(EncodeResponse {
input,
dict: dict_name,
result: encoded_parts,
}))
}
pub async fn decode_handler(
State(state): State<Arc<AppState>>,
Path(input): Path<String>,
Query(_params): Query<DecodeQuery>,
) -> Result<Json<DecodeResponse>, ErrorResponse> {
let decoder = state
.container
.create_decoder()
.map_err(|e| anyhow::anyhow!("Failed to create decoder: {}", e))?;
let result = decoder
.decode(&input)
.map_err(|e| anyhow::anyhow!("Failed to decode: {}", e))?;
Ok(Json(DecodeResponse {
input,
result: result.as_str().to_string(),
}))
}
pub fn routes() -> Router<Arc<AppState>> {
Router::new()
.route("/encode/major_pl/{input}", get(encode_handler))
.route("/decode/major_pl/{input}", get(decode_handler))
}

15
apps/app_api/src/container.rs

@ -28,4 +28,19 @@ impl Container {
dict_repo.use_dict(dict_name); dict_repo.use_dict(dict_name);
Ok(Arc::new(dict_repo)) Ok(Arc::new(dict_repo))
} }
pub fn create_decoder(&self) -> anyhow::Result<Box<dyn SystemDecoder>> {
Ok(Box::new(major::Decoder::new(major::rules_pl::get_rules())))
}
pub async fn create_encoder(&self, dict_name: &str) -> anyhow::Result<Box<dyn SystemEncoder>> {
let dict = self.create_dict_repo(dict_name).await?;
let decoder = self.create_decoder()?;
let words_stream = dict.stream_batches(1000).await.unwrap();
let lvmap = major::LenValueMap::from_stream(words_stream, &(*decoder))
.await
.unwrap();
let encoder = major::Encoder::new(lvmap);
Ok(Box::new(encoder))
}
} }

Loading…
Cancel
Save