diff --git a/Cargo.lock b/Cargo.lock index 70a54258..defafbe8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1059,12 +1059,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.8", + "darling_macro 0.20.8", ] [[package]] @@ -1083,9 +1083,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", @@ -1108,11 +1108,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.8", "quote", "syn 2.0.48", ] @@ -1291,6 +1291,12 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + [[package]] name = "dyn-stack" version = "0.10.0" @@ -1833,6 +1839,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "h2" version = "0.3.24" @@ -2321,6 +2340,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "0.4.8" @@ -2986,6 +3014,17 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openapiv3" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc02deea53ffe807708244e5914f6b099ad7015a207ee24317c22112e17d9c5c" +dependencies = [ + "indexmap 2.2.3", + "serde", + "serde_json", +] + [[package]] name = "openssl" version = "0.10.63" @@ -3040,6 +3079,7 @@ dependencies = [ "logos", "once_cell", "serde", + "tapi", "thiserror", "utoipa", ] @@ -4140,7 +4180,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb6085ff9c3fd7e5163826901d39164ab86f11bdca16b2f766a00c528ff9cef9" dependencies = [ - "darling 0.20.3", + "darling 0.20.8", "proc-macro2", "quote", "syn 2.0.48", @@ -4203,18 +4243,40 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2", "quote", @@ -4223,9 +4285,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.113" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa 1.0.10", "ryu", @@ -4516,6 +4578,7 @@ dependencies = [ "serde_json", "serde_urlencoded", "tantivy", + "tapi", "thiserror", "tikv-jemallocator", "tokenizers", @@ -4810,6 +4873,36 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +[[package]] +name = "tapi" +version = "0.1.0" +dependencies = [ + "axum", + "dyn-clone", + "futures-util", + "heck 0.4.1", + "indexmap 2.2.3", + "itertools 0.12.1", + "openapiv3", + "serde", + "serde_json", + "tapi-macro", + "tsify", +] + +[[package]] +name = "tapi-macro" +version = "0.1.0" +dependencies = [ + "darling 0.20.8", + "heck 0.4.1", + "prettyplease", + "proc-macro2", + "quote", + "serde_derive_internals 0.29.0", + "syn 2.0.48", +] + [[package]] name = "tar" version = "0.4.40" @@ -5250,6 +5343,31 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals 0.28.0", + "syn 2.0.48", +] + [[package]] name = "twox-hash" version = "1.6.3" diff --git a/Cargo.toml b/Cargo.toml index d5ca6e25..fb9bfba0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,6 +94,7 @@ serde = {version = "1.0.137", features = ["rc", "derive"]} serde_json = "1.0.81" serde_urlencoded = "0.7.1" tantivy = {git = "https://github.com/quickwit-oss/tantivy", rev = "182f58cea"} +tapi = {path = "../tapi/crates/tapi/", package = "tapi", features = ["openapi"]} thiserror = "1.0.31" tikv-jemallocator = "0.5" tokenizers = "0.13.2" diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index 229f6456..172a1566 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -88,6 +88,7 @@ serde = {workspace = true} serde_json = {workspace = true} serde_urlencoded = {workspace = true} tantivy = {workspace = true} +tapi = {workspace = true} thiserror = {workspace = true} tokenizers = {workspace = true} tokio = {workspace = true} diff --git a/crates/core/src/api/autosuggest.rs b/crates/core/src/api/autosuggest.rs index 9a1d973e..00b81719 100644 --- a/crates/core/src/api/autosuggest.rs +++ b/crates/core/src/api/autosuggest.rs @@ -14,13 +14,11 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -use std::{collections::HashMap, sync::Arc}; - -use axum::{extract, response::IntoResponse, Json}; +use axum::{extract, Json}; use serde::Serialize; use utoipa::{IntoParams, ToSchema}; -use super::State; +use super::AppState; const HIGHLIGHTED_PREFIX: &str = ""; const HIGHLIGHTED_POSTFIX: &str = ""; @@ -39,17 +37,17 @@ fn highlight(query: &str, suggestion: &str) -> String { new_suggestion } -#[derive(Serialize, ToSchema)] +#[derive(Serialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct Suggestion { highlighted: String, raw: String, } -#[derive(Debug, serde::Serialize, serde::Deserialize, IntoParams)] +#[derive(Debug, serde::Serialize, serde::Deserialize, IntoParams, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct AutosuggestQuery { - q: String, + q: Option, } #[utoipa::path( @@ -60,12 +58,12 @@ pub struct AutosuggestQuery { (status = 200, description = "Autosuggest", body = Vec), ) )] - +#[tapi::tapi(path = "/autosuggest", method = Post, state = AppState)] pub async fn route( - extract::State(state): extract::State>, - extract::Query(params): extract::Query>, -) -> impl IntoResponse { - if let Some(query) = params.get("q") { + extract::State(state): extract::State, + extract::Query(params): extract::Query, +) -> Json> { + if let Some(query) = ¶ms.q { let mut suggestions = Vec::new(); for suggestion in state.autosuggest.suggestions(query).unwrap() { @@ -82,11 +80,12 @@ pub async fn route( } } +#[tapi::tapi(path = "/autosuggest/browser", method = Post, state = AppState)] pub async fn browser( - extract::State(state): extract::State>, - extract::Query(params): extract::Query>, -) -> impl IntoResponse { - if let Some(query) = params.get("q") { + extract::State(state): extract::State, + extract::Query(params): extract::Query, +) -> Json<(String, Vec)> { + if let Some(query) = ¶ms.q { Json((query.clone(), state.autosuggest.suggestions(query).unwrap())) } else { Json((String::new(), Vec::new())) diff --git a/crates/core/src/api/explore.rs b/crates/core/src/api/explore.rs index 979e4516..2fdc941f 100644 --- a/crates/core/src/api/explore.rs +++ b/crates/core/src/api/explore.rs @@ -15,11 +15,10 @@ // along with this program. If not, see . use axum::extract; -use http::StatusCode; use optics::{HostRankings, Optic}; use utoipa::ToSchema; -#[derive(serde::Deserialize, ToSchema)] +#[derive(serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct ExploreExportOpticParams { chosen_hosts: Vec, @@ -34,12 +33,13 @@ pub struct ExploreExportOpticParams { (status = 200, description = "Export explored sites as an optic", body = String), ) )] +#[tapi::tapi(path = "/expore/export", method = Post)] pub async fn explore_export_optic( extract::Json(ExploreExportOpticParams { chosen_hosts, similar_hosts, }): extract::Json, -) -> Result { +) -> String { let matches = similar_hosts .into_iter() .chain(chosen_hosts.clone().into_iter()) @@ -69,5 +69,5 @@ pub async fn explore_export_optic( ..Default::default() }; - Ok(optic.to_string()) + optic.to_string() } diff --git a/crates/core/src/api/hosts.rs b/crates/core/src/api/hosts.rs index cf54d18c..8dd4ccad 100644 --- a/crates/core/src/api/hosts.rs +++ b/crates/core/src/api/hosts.rs @@ -15,11 +15,10 @@ // along with this program. If not, see . use axum::{extract, Json}; -use http::StatusCode; use optics::{HostRankings, Optic}; use utoipa::ToSchema; -#[derive(serde::Deserialize, ToSchema)] +#[derive(serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct HostsExportOpticParams { host_rankings: HostRankings, @@ -32,13 +31,14 @@ pub struct HostsExportOpticParams { (status = 200, description = "Export host rankings as an optic", body = String), ) )] +#[tapi::tapi(path = "/hosts/export", method = Post)] pub async fn hosts_export_optic( extract::Json(HostsExportOpticParams { host_rankings }): extract::Json, -) -> Result, StatusCode> { +) -> Json { let optic = Optic { host_rankings, ..Default::default() }; - Ok(Json(optic.to_string())) + Json(optic.to_string()) } diff --git a/crates/core/src/api/improvement.rs b/crates/core/src/api/improvement.rs index fb8cd112..e676a6c7 100644 --- a/crates/core/src/api/improvement.rs +++ b/crates/core/src/api/improvement.rs @@ -23,7 +23,7 @@ use uuid::Uuid; use crate::improvement::{ImprovementEvent, StoredQuery}; -use super::State; +use super::AppState; #[derive(Deserialize, Debug)] pub struct ClickParams { @@ -39,7 +39,7 @@ pub struct StoreParams { pub async fn click( extract::Query(params): extract::Query, - extract::State(state): extract::State>, + extract::State(state): extract::State, ) { if let Some(q) = state.improvement_queue.as_ref() { q.lock().await.push(ImprovementEvent::Click { @@ -62,7 +62,7 @@ impl TryFrom for StoredQuery { } pub async fn store( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(params): extract::Json, ) -> impl IntoResponse { match state.improvement_queue.as_ref() { diff --git a/crates/core/src/api/mod.rs b/crates/core/src/api/mod.rs index 37ba6b10..624f434b 100644 --- a/crates/core/src/api/mod.rs +++ b/crates/core/src/api/mod.rs @@ -70,6 +70,7 @@ pub struct Counters { pub daily_active_users: user_count::UserCount, } +pub type AppState = Arc; pub struct State { pub config: ApiConfig, pub searcher: ApiSearcher, @@ -206,6 +207,32 @@ pub async fn router(config: &ApiConfig, counters: Counters) -> Result { .with_state(state)) } +pub fn endpoints() -> tapi::endpoints::Endpoints<'static, AppState> { + type E = &'static dyn tapi::endpoints::Endpoint; + + tapi::endpoints::Endpoints::new([ + &autosuggest::browser::endpoint as E, + &autosuggest::route::endpoint as E, + &explore::explore_export_optic::endpoint as E, + // &favicon::endpoint as E, + &hosts::hosts_export_optic::endpoint as E, + // &improvement::click::endpoint as E, + // &improvement::store::endpoint as E, + // &search::entity_image::endpoint as E, + &search::search::endpoint as E, + &search::sidebar::endpoint as E, + &search::spellcheck::endpoint as E, + &search::widget::endpoint as E, + // &summarize::summarize_route::endpoint as E, + &webgraph::host::ingoing_hosts::endpoint as E, + &webgraph::host::knows::endpoint as E, + &webgraph::host::outgoing_hosts::endpoint as E, + &webgraph::host::similar::endpoint as E, + &webgraph::page::ingoing_pages::endpoint as E, + &webgraph::page::outgoing_pages::endpoint as E, + ]) +} + /// Enables CORS for development where the API and frontend are on /// different hosts. fn cors_layer() -> tower_http::cors::CorsLayer { @@ -222,7 +249,7 @@ pub fn metrics_router(registry: crate::metrics::PrometheusRegistry) -> Router { } async fn search_metric( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::ConnectInfo(addr): extract::ConnectInfo, request: axum::extract::Request, next: middleware::Next, diff --git a/crates/core/src/api/search.rs b/crates/core/src/api/search.rs index 94bf3c20..fa17f1db 100644 --- a/crates/core/src/api/search.rs +++ b/crates/core/src/api/search.rs @@ -17,7 +17,6 @@ use crate::config::defaults; use http::StatusCode; use optics::{HostRankings, Optic}; -use std::sync::Arc; use utoipa::ToSchema; use axum::Json; @@ -29,11 +28,11 @@ use crate::{ webpage::region::Region, }; -use super::State; +use super::AppState; use axum::{extract, response::IntoResponse}; -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] #[schema(title = "SearchQuery", example = json!({"query": "hello world"}))] pub struct ApiSearchQuery { @@ -81,7 +80,7 @@ impl TryFrom for SearchQuery { } } -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(tag = "type", rename_all = "camelCase")] pub enum ApiSearchResult { Websites(WebsitesResult), @@ -106,17 +105,24 @@ impl From for ApiSearchResult { (status = 200, description = "Search results", body = ApiSearchResult), ) )] +#[tapi::tapi(path = "/search", method = Post, state = AppState)] pub async fn search( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(query): extract::Json, -) -> Result { +) -> tapi::endpoints::OneOf5< + extract::Json, + extract::Json, + String, + tapi::endpoints::Statused<400, ()>, + tapi::endpoints::Statused<500, ()>, +> { tracing::debug!(?query); let flatten_result = query.flatten_response; let query = SearchQuery::try_from(query); if let Err(err) = query { tracing::error!("{:?}", err); - return Err(StatusCode::BAD_REQUEST); + return tapi::endpoints::OneOf5::D(().into()); } let mut query = query.unwrap(); @@ -125,27 +131,25 @@ pub async fn search( match state.searcher.search(&query).await { Ok(result) => { if flatten_result { - Ok(Json(ApiSearchResult::from(result)).into_response()) + tapi::endpoints::OneOf5::A(Json(ApiSearchResult::from(result))) } else { - Ok(Json(result).into_response()) + tapi::endpoints::OneOf5::B(Json(result)) } } Err(err) => match err.downcast_ref() { Some(searcher::distributed::Error::EmptyQuery) => { - Ok(searcher::distributed::Error::EmptyQuery - .to_string() - .into_response()) + tapi::endpoints::OneOf5::C(searcher::distributed::Error::EmptyQuery.to_string()) } _ => { tracing::error!("{:?}", err); - Err(StatusCode::INTERNAL_SERVER_ERROR) + tapi::endpoints::OneOf5::E(().into()) } }, } } -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] pub struct WidgetQuery { pub query: String, } @@ -159,14 +163,15 @@ pub struct WidgetQuery { (status = 200, description = "The resulting widget if one matches the query", body = Option), ) )] +#[tapi::tapi(path = "/search/widget", method = Post, state = AppState)] pub async fn widget( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(req): extract::Json, -) -> impl IntoResponse { +) -> extract::Json> { Json(state.searcher.widget(&req.query).await) } -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] pub struct SidebarQuery { pub query: String, } @@ -180,14 +185,15 @@ pub struct SidebarQuery { (status = 200, description = "The sidebar if one matches the query", body = Option), ) )] +#[tapi::tapi(path = "/search/sidebar", method = Post, state = AppState)] pub async fn sidebar( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(req): extract::Json, -) -> impl IntoResponse { +) -> Json> { Json(state.searcher.sidebar(&req.query).await) } -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] pub struct SpellcheckQuery { pub query: String, } @@ -201,14 +207,15 @@ pub struct SpellcheckQuery { (status = 200, description = "The corrected string with the changes highlighted using ...<\\b> elements. Returns empty response if there is no correction to be made.", body = Option), ) )] +#[tapi::tapi(path = "/search/spellcheck", method = Post, state = AppState)] pub async fn spellcheck( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(req): extract::Json, -) -> impl IntoResponse { +) -> Json> { Json(state.searcher.spell_check(&req.query)) } -#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(Debug, serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct EntityImageParams { pub image_id: String, @@ -224,9 +231,11 @@ pub struct EntityImageParams { (status = 200, description = "Search results", body = ApiSearchResult), ) )] +// TODO +// #[tapi::tapi(path = "/entity_image", method = Post, state = AppState)] pub async fn entity_image( extract::Query(query): extract::Query, - extract::State(state): extract::State>, + extract::State(state): extract::State, ) -> Result { match state .searcher diff --git a/crates/core/src/api/summarize.rs b/crates/core/src/api/summarize.rs index 99dbf94e..b2d13da9 100644 --- a/crates/core/src/api/summarize.rs +++ b/crates/core/src/api/summarize.rs @@ -26,7 +26,7 @@ use serde::Deserialize; use tokio_stream::StreamExt as _; use utoipa::IntoParams; -use super::State; +use super::AppState; use crate::Result; #[derive(Deserialize, Debug, IntoParams)] @@ -37,7 +37,7 @@ pub struct SummarizeParams { async fn summarize( params: SummarizeParams, - state: Arc, + state: AppState, ) -> Result>>> { let webpage = state .searcher @@ -70,7 +70,7 @@ async fn summarize( )] pub async fn summarize_route( extract::Query(params): extract::Query, - extract::State(state): extract::State>, + extract::State(state): extract::State, ) -> std::result::Result>>, StatusCode> { // err might actually happen if url contains more than 255 tokens diff --git a/crates/core/src/api/webgraph.rs b/crates/core/src/api/webgraph.rs index 771b7ac1..3dc64447 100644 --- a/crates/core/src/api/webgraph.rs +++ b/crates/core/src/api/webgraph.rs @@ -26,7 +26,7 @@ use crate::{ webgraph::{FullEdge, Node}, }; -use super::State; +use super::AppState; pub struct RemoteWebgraph { cluster: Arc, @@ -52,22 +52,24 @@ impl RemoteWebgraph { pub mod host { use url::Url; + use crate::entrypoint::webgraph_server::ScoredHost; + use super::*; - #[derive(serde::Deserialize, ToSchema)] + #[derive(serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct SimilarHostsParams { pub hosts: Vec, pub top_n: usize, } - #[derive(serde::Deserialize, IntoParams)] + #[derive(serde::Deserialize, IntoParams, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct KnowsHostParams { pub host: String, } - #[derive(serde::Deserialize, IntoParams)] + #[derive(serde::Deserialize, IntoParams, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct HostLinksParams { pub host: String, @@ -80,28 +82,29 @@ pub mod host { (status = 200, description = "List of similar hosts", body = Vec), ) )] + #[tapi::tapi(path = "/host/similar", method = Post, state = AppState)] pub async fn similar( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Json(params): extract::Json, - ) -> std::result::Result { + ) -> tapi::endpoints::OneOf2>, tapi::endpoints::Statused<500, ()>> { state.counters.explore_counter.inc(); - let host = state - .remote_webgraph - .host(WebgraphGranularity::Host) - .await - .ok_or(StatusCode::INTERNAL_SERVER_ERROR)?; + let Some(host) = state.remote_webgraph.host(WebgraphGranularity::Host).await else { + return tapi::endpoints::OneOf2::B(().into()); + }; let retry = ExponentialBackoff::from_millis(30) .with_limit(Duration::from_millis(200)) .take(5); - let conn = sonic::service::ResilientConnection::create_with_timeout( + let Ok(conn) = sonic::service::ResilientConnection::create_with_timeout( host, Duration::from_secs(30), retry, ) .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + else { + return tapi::endpoints::OneOf2::B(().into()); + }; match conn .send_with_timeout( @@ -113,10 +116,10 @@ pub mod host { ) .await { - Ok(nodes) => Ok(Json(nodes)), + Ok(nodes) => tapi::endpoints::OneOf2::A(Json(nodes)), Err(err) => { tracing::error!("Failed to send request to webgraph: {}", err); - Err(StatusCode::INTERNAL_SERVER_ERROR) + tapi::endpoints::OneOf2::B(().into()) } } } @@ -128,42 +131,44 @@ pub mod host { (status = 200, description = "Whether the host is known", body = KnowsHost), ) )] + #[tapi::tapi(path = "/host/knows", method = Post, state = AppState)] pub async fn knows( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Query(params): extract::Query, - ) -> std::result::Result { - let host = state - .remote_webgraph - .host(WebgraphGranularity::Host) - .await - .ok_or(StatusCode::INTERNAL_SERVER_ERROR)?; + ) -> tapi::endpoints::OneOf2, tapi::endpoints::Statused<500, ()>> { + let Some(host) = state.remote_webgraph.host(WebgraphGranularity::Host).await else { + return tapi::endpoints::OneOf2::B(().into()); + }; let retry = ExponentialBackoff::from_millis(30) .with_limit(Duration::from_millis(200)) .take(5); - let conn = sonic::service::ResilientConnection::create_with_timeout( + let Ok(conn) = sonic::service::ResilientConnection::create_with_timeout( host, Duration::from_secs(30), retry, ) .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + else { + return tapi::endpoints::OneOf2::B(().into()); + }; - match conn + let response = match conn .send_with_timeout( &crate::entrypoint::webgraph_server::Knows { host: params.host }, Duration::from_secs(60), ) .await { - Ok(Some(node)) => Ok(Json(KnowsHost::Known { host: node.name })), + Ok(Some(node)) => Json(KnowsHost::Known { host: node.name }), Err(err) => { tracing::error!("Failed to send request to webgraph: {}", err); - Ok(Json(KnowsHost::Unknown)) + Json(KnowsHost::Unknown) } - _ => Ok(Json(KnowsHost::Unknown)), - } + _ => Json(KnowsHost::Unknown), + }; + tapi::endpoints::OneOf2::A(response) } #[utoipa::path(post, @@ -173,21 +178,21 @@ pub mod host { (status = 200, description = "Incoming links for a particular host", body = Vec), ) )] + #[tapi::tapi(path = "/host/ingoing", method = Post, state = AppState)] pub async fn ingoing_hosts( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Query(params): extract::Query, - ) -> std::result::Result { - let url = Url::parse(&("http://".to_string() + params.host.as_str())) - .map_err(|_| StatusCode::BAD_REQUEST)?; + ) -> tapi::endpoints::OneOf2>, tapi::endpoints::Statused<500, ()>> { + let Ok(url) = Url::parse(&("http://".to_string() + params.host.as_str())) else { + return tapi::endpoints::OneOf2::B(().into()); + }; let node = Node::from(url).into_host(); - let links = ingoing_links(state, node, WebgraphGranularity::Host) - .await - .map_err(|_| { - tracing::error!("Failed to send request to webgraph"); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let Ok(links) = ingoing_links(state, node, WebgraphGranularity::Host).await else { + tracing::error!("Failed to send request to webgraph"); + return tapi::endpoints::OneOf2::B(().into()); + }; - Ok(Json(links)) + tapi::endpoints::OneOf2::A(Json(links)) } #[utoipa::path(post, @@ -197,28 +202,28 @@ pub mod host { (status = 200, description = "Outgoing links for a particular host", body = Vec), ) )] + #[tapi::tapi(path = "/host/outgoing", method = Post, state = AppState)] pub async fn outgoing_hosts( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Query(params): extract::Query, - ) -> std::result::Result { - let url = Url::parse(&("http://".to_string() + params.host.as_str())) - .map_err(|_| StatusCode::BAD_REQUEST)?; + ) -> tapi::endpoints::OneOf2>, tapi::endpoints::Statused<500, ()>> { + let Ok(url) = Url::parse(&("http://".to_string() + params.host.as_str())) else { + return tapi::endpoints::OneOf2::B(().into()); + }; let node = Node::from(url).into_host(); - let links = outgoing_links(state, node, WebgraphGranularity::Host) - .await - .map_err(|_| { - tracing::error!("Failed to send request to webgraph"); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let Ok(links) = outgoing_links(state, node, WebgraphGranularity::Host).await else { + tracing::error!("Failed to send request to webgraph"); + return tapi::endpoints::OneOf2::B(().into()); + }; - Ok(Json(links)) + tapi::endpoints::OneOf2::A(Json(links)) } } pub mod page { use super::*; - #[derive(serde::Deserialize, IntoParams)] + #[derive(serde::Deserialize, IntoParams, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct PageLinksParams { pub page: String, @@ -231,19 +236,18 @@ pub mod page { (status = 200, description = "Incoming links for a particular page", body = Vec), ) )] + #[tapi::tapi(path = "/page/ingoing", method = Post, state = AppState)] pub async fn ingoing_pages( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Query(params): extract::Query, - ) -> std::result::Result { + ) -> tapi::endpoints::OneOf2>, tapi::endpoints::Statused<500, ()>> { let node = Node::from(params.page); - let links = ingoing_links(state, node, WebgraphGranularity::Page) - .await - .map_err(|_| { - tracing::error!("Failed to send request to webgraph"); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let Ok(links) = ingoing_links(state, node, WebgraphGranularity::Page).await else { + tracing::error!("Failed to send request to webgraph"); + return tapi::endpoints::OneOf2::B(().into()); + }; - Ok(Json(links)) + tapi::endpoints::OneOf2::A(Json(links)) } #[utoipa::path(post, @@ -253,24 +257,23 @@ pub mod page { (status = 200, description = "Outgoing links for a particular page", body = Vec), ) )] + #[tapi::tapi(path = "/page/outgoing", method = Post, state = AppState)] pub async fn outgoing_pages( - extract::State(state): extract::State>, + extract::State(state): extract::State, extract::Query(params): extract::Query, - ) -> std::result::Result { + ) -> tapi::endpoints::OneOf2>, tapi::endpoints::Statused<500, ()>> { let node = Node::from(params.page); - let links = outgoing_links(state, node, WebgraphGranularity::Page) - .await - .map_err(|_| { - tracing::error!("Failed to send request to webgraph"); - StatusCode::INTERNAL_SERVER_ERROR - })?; + let Ok(links) = outgoing_links(state, node, WebgraphGranularity::Page).await else { + tracing::error!("Failed to send request to webgraph"); + return tapi::endpoints::OneOf2::B(().into()); + }; - Ok(Json(links)) + tapi::endpoints::OneOf2::A(Json(links)) } } async fn ingoing_links( - state: Arc, + state: AppState, node: Node, level: WebgraphGranularity, ) -> anyhow::Result> { @@ -302,7 +305,7 @@ async fn ingoing_links( } async fn outgoing_links( - state: Arc, + state: AppState, node: Node, level: WebgraphGranularity, ) -> anyhow::Result> { @@ -333,7 +336,7 @@ async fn outgoing_links( .await?) } -#[derive(serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(tag = "type", rename_all = "camelCase")] pub enum KnowsHost { Known { host: String }, diff --git a/crates/core/src/bangs.rs b/crates/core/src/bangs.rs index 70b3b57e..f53ef5b1 100644 --- a/crates/core/src/bangs.rs +++ b/crates/core/src/bangs.rs @@ -30,7 +30,7 @@ use crate::query::parser::Term; pub const BANG_PREFIXES: [char; 2] = ['!', '!']; -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct Bang { #[serde(rename = "c")] @@ -60,6 +60,16 @@ pub struct Bang { #[schema(value_type = String, title = "Url")] pub struct UrlWrapper(Url); +impl tapi::Tapi for UrlWrapper { + fn name() -> &'static str { + "Url" + } + + fn kind() -> tapi::kind::TypeKind { + tapi::kind::TypeKind::Builtin(tapi::kind::BuiltinTypeKind::String) + } +} + impl DerefMut for UrlWrapper { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 @@ -80,7 +90,7 @@ impl From for UrlWrapper { } } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct BangHit { pub bang: Bang, diff --git a/crates/core/src/entity_index/entity.rs b/crates/core/src/entity_index/entity.rs index ab1b4abf..ad0304ff 100644 --- a/crates/core/src/entity_index/entity.rs +++ b/crates/core/src/entity_index/entity.rs @@ -94,14 +94,16 @@ pub struct Link { pub target: String, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase", tag = "kind")] pub enum EntitySnippetFragment { Normal { text: String }, Link { text: String, href: String }, } -#[derive(Default, Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] +#[derive( + Default, Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema, tapi::Tapi, +)] #[serde(rename_all = "camelCase")] pub struct EntitySnippet { pub fragments: Vec, diff --git a/crates/core/src/entrypoint/api.rs b/crates/core/src/entrypoint/api.rs index dabf5dd2..4e5a16ff 100644 --- a/crates/core/src/entrypoint/api.rs +++ b/crates/core/src/entrypoint/api.rs @@ -26,6 +26,9 @@ use crate::{ }; pub async fn run(config: config::ApiConfig) -> Result<()> { + let endpoints = crate::api::endpoints(); + println!("{}", endpoints.ts_client()); + let search_counter_success = crate::metrics::Counter::default(); let search_counter_fail = crate::metrics::Counter::default(); let explore_counter = crate::metrics::Counter::default(); diff --git a/crates/core/src/entrypoint/webgraph_server.rs b/crates/core/src/entrypoint/webgraph_server.rs index 578cb576..7c6de18e 100644 --- a/crates/core/src/entrypoint/webgraph_server.rs +++ b/crates/core/src/entrypoint/webgraph_server.rs @@ -43,7 +43,7 @@ use crate::webgraph::Webgraph; use crate::webgraph::WebgraphBuilder; use crate::Result; -#[derive(serde::Serialize, serde::Deserialize, ToSchema)] +#[derive(serde::Serialize, serde::Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct ScoredHost { pub host: String, diff --git a/crates/core/src/ranking/signal.rs b/crates/core/src/ranking/signal.rs index 1422ae0e..5c5644c1 100644 --- a/crates/core/src/ranking/signal.rs +++ b/crates/core/src/ranking/signal.rs @@ -56,7 +56,9 @@ pub enum Error { UnknownSignal(#[from] serde_json::Error), } -#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq, Hash)] +#[derive( + Debug, serde::Serialize, serde::Deserialize, Clone, Copy, PartialEq, Eq, Hash, tapi::Tapi, +)] pub enum Signal { #[serde(rename = "bm25_title")] Bm25Title, @@ -1006,7 +1008,7 @@ pub struct ComputedSignal { pub score: SignalScore, } -#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, Copy, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct SignalScore { pub coefficient: f64, diff --git a/crates/core/src/search_prettifier/entity.rs b/crates/core/src/search_prettifier/entity.rs index 1d0e310c..543b593c 100644 --- a/crates/core/src/search_prettifier/entity.rs +++ b/crates/core/src/search_prettifier/entity.rs @@ -24,7 +24,7 @@ use crate::entity_index::{ EntityMatch, }; -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct DisplayedEntity { pub title: String, diff --git a/crates/core/src/search_prettifier/mod.rs b/crates/core/src/search_prettifier/mod.rs index 70a26e88..5d2aa35e 100644 --- a/crates/core/src/search_prettifier/mod.rs +++ b/crates/core/src/search_prettifier/mod.rs @@ -37,7 +37,7 @@ pub use entity::DisplayedEntity; pub use self::stack_overflow::{stackoverflow_snippet, StackOverflowAnswer, StackOverflowQuestion}; -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(tag = "type", rename_all = "camelCase")] pub enum Snippet { Normal { @@ -59,7 +59,7 @@ impl Snippet { } } -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct HighlightedSpellCorrection { pub raw: String, @@ -165,7 +165,7 @@ fn generate_snippet(webpage: &RetrievedWebpage) -> Snippet { } } -#[derive(Debug, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct DisplayedWebpage { pub title: String, @@ -180,7 +180,7 @@ pub struct DisplayedWebpage { pub likely_has_paywall: bool, } -#[derive(Debug, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct DisplayedAnswer { pub title: String, @@ -213,7 +213,7 @@ impl From for DisplayedWebpage { } } -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(tag = "type", content = "value", rename_all = "camelCase")] pub enum DisplayedSidebar { Entity(DisplayedEntity), diff --git a/crates/core/src/search_prettifier/stack_overflow.rs b/crates/core/src/search_prettifier/stack_overflow.rs index 25dc8eab..8324c1c7 100644 --- a/crates/core/src/search_prettifier/stack_overflow.rs +++ b/crates/core/src/search_prettifier/stack_overflow.rs @@ -27,7 +27,7 @@ use crate::{ use super::{DisplayedSidebar, Snippet}; use crate::Result; -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct StackOverflowAnswer { pub body: Vec, @@ -37,13 +37,13 @@ pub struct StackOverflowAnswer { pub accepted: bool, } -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct StackOverflowQuestion { pub body: Vec, } -#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(tag = "type", content = "value", rename_all = "camelCase")] pub enum CodeOrText { Code(String), diff --git a/crates/core/src/searcher/mod.rs b/crates/core/src/searcher/mod.rs index 0a50dd58..b5a81997 100644 --- a/crates/core/src/searcher/mod.rs +++ b/crates/core/src/searcher/mod.rs @@ -32,13 +32,13 @@ use crate::{ pub const NUM_RESULTS_PER_PAGE: usize = 20; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, tapi::Tapi)] pub enum SearchResult { Websites(WebsitesResult), Bang(Box), } -#[derive(Debug, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct WebsitesResult { pub webpages: Vec, diff --git a/crates/core/src/snippet.rs b/crates/core/src/snippet.rs index bd7065b2..e380913a 100644 --- a/crates/core/src/snippet.rs +++ b/crates/core/src/snippet.rs @@ -46,14 +46,14 @@ struct PassageCandidate { doc_terms: HashMap, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub enum TextSnippetFragmentKind { Normal, Highlighted, } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] +#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct TextSnippetFragment { pub kind: TextSnippetFragmentKind, @@ -73,7 +73,9 @@ impl TextSnippetFragment { } } -#[derive(Default, Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema)] +#[derive( + Default, Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, ToSchema, tapi::Tapi, +)] #[serde(rename_all = "camelCase")] pub struct TextSnippet { pub fragments: Vec, diff --git a/crates/core/src/webgraph/mod.rs b/crates/core/src/webgraph/mod.rs index f47b7bd1..f8084018 100644 --- a/crates/core/src/webgraph/mod.rs +++ b/crates/core/src/webgraph/mod.rs @@ -148,7 +148,9 @@ where } } -#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, ToSchema)] +#[derive( + Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq, Hash, ToSchema, tapi::Tapi, +)] #[serde(rename_all = "camelCase")] pub struct FullEdge { pub from: Node, @@ -167,6 +169,7 @@ pub struct FullEdge { serde::Serialize, serde::Deserialize, ToSchema, + tapi::Tapi, )] #[serde(rename_all = "camelCase")] pub struct Node { diff --git a/crates/core/src/webpage/region.rs b/crates/core/src/webpage/region.rs index f7496226..2d9f4a49 100644 --- a/crates/core/src/webpage/region.rs +++ b/crates/core/src/webpage/region.rs @@ -23,7 +23,9 @@ use crate::{Error, Result}; use super::Webpage; -#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize, Default, ToSchema)] +#[derive( + Debug, PartialEq, Eq, Clone, Copy, Hash, Serialize, Deserialize, Default, ToSchema, tapi::Tapi, +)] pub enum Region { #[default] All, diff --git a/crates/core/src/widgets/calculator.rs b/crates/core/src/widgets/calculator.rs index 5d260032..9eb12fef 100644 --- a/crates/core/src/widgets/calculator.rs +++ b/crates/core/src/widgets/calculator.rs @@ -28,7 +28,7 @@ use utoipa::ToSchema; static DICE_REGEX: once_cell::sync::Lazy = once_cell::sync::Lazy::new(|| regex::Regex::new(r"^d[0-9]+").unwrap()); -#[derive(Debug, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct Calculation { pub input: String, diff --git a/crates/core/src/widgets/mod.rs b/crates/core/src/widgets/mod.rs index 57d1d4d1..29647e5b 100644 --- a/crates/core/src/widgets/mod.rs +++ b/crates/core/src/widgets/mod.rs @@ -78,7 +78,7 @@ impl Widgets { } } -#[derive(Debug, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(tag = "type", content = "value", rename_all = "camelCase")] pub enum Widget { Calculator(Calculation), diff --git a/crates/core/src/widgets/thesaurus.rs b/crates/core/src/widgets/thesaurus.rs index adeed6a2..c62f5d16 100644 --- a/crates/core/src/widgets/thesaurus.rs +++ b/crates/core/src/widgets/thesaurus.rs @@ -25,7 +25,7 @@ use rio_api::parser::TriplesParser; use rio_turtle::TurtleParser; use std::collections::HashMap; -#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase", transparent)] pub struct Lemma(String); @@ -41,15 +41,17 @@ impl Lemma { #[derive(Debug, Clone, PartialEq, Eq, Hash)] struct Id(String); -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase", transparent)] pub struct Definition(String); -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase", transparent)] pub struct Example(String); -#[derive(Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema)] +#[derive( + Debug, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Serialize, Deserialize, ToSchema, tapi::Tapi, +)] #[serde(rename_all = "camelCase")] pub enum PartOfSpeech { Noun, @@ -456,7 +458,7 @@ impl Dictionary { } } -#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct WordMeaning { pub definition: Definition, @@ -464,7 +466,7 @@ pub struct WordMeaning { pub similar: Vec, } -#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct PartOfSpeechMeaning { pub pos: PartOfSpeech, @@ -491,7 +493,7 @@ impl PartialOrd for PartOfSpeechMeaning { } } -#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct ThesaurusWidget { pub term: Lemma, diff --git a/crates/optics-lsp/Cargo.lock b/crates/optics-lsp/Cargo.lock index cf57baaa..46b4f8d0 100644 --- a/crates/optics-lsp/Cargo.lock +++ b/crates/optics-lsp/Cargo.lock @@ -2,6 +2,21 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "0.7.20" @@ -20,12 +35,93 @@ dependencies = [ "term", ] +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1236b4b292f6c4d6dc34604bb5120d85c3fe1d1aa596bd5cc52ca054d13e7b9e" +dependencies = [ + "async-trait", + "axum-core", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "beef" version = "0.5.2" @@ -65,6 +161,18 @@ version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "cc" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24" + [[package]] name = "cfg-if" version = "1.0.0" @@ -87,6 +195,41 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + [[package]] name = "diff" version = "0.1.13" @@ -114,6 +257,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + [[package]] name = "either" version = "1.8.1" @@ -166,6 +315,58 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + [[package]] name = "getrandom" version = "0.2.8" @@ -177,6 +378,44 @@ dependencies = [ "wasi", ] +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "h2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.3", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -185,9 +424,15 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" @@ -195,6 +440,94 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.3.0" @@ -217,12 +550,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.0" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.14.3", "serde", ] @@ -313,9 +646,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "linux-raw-sys" @@ -387,24 +720,76 @@ dependencies = [ "url", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + [[package]] name = "new_debug_unreachable" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +[[package]] +name = "openapiv3" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc02deea53ffe807708244e5914f6b099ad7015a207ee24317c22112e17d9c5c" +dependencies = [ + "indexmap 2.2.3", + "serde", + "serde_json", +] + [[package]] name = "optics" version = "0.1.0" @@ -415,6 +800,7 @@ dependencies = [ "logos", "once_cell", "serde", + "tapi", "thiserror", "utoipa", ] @@ -488,12 +874,54 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "precomputed-hash" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -579,6 +1007,12 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "rustix" version = "0.38.19" @@ -612,9 +1046,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "serde" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -632,9 +1066,31 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.196" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2", "quote", @@ -643,15 +1099,25 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.94" +version = "1.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c533a59c9d8a93a09c6ab31f0fd5e5f4dd1b8fc9434804029839884765d04ea" +checksum = "c5f09b1bd632ef549eaa9f60a1f8de742bdbc698e6cee2095fc84dde5f549ae0" dependencies = [ "itoa", "ryu", "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +dependencies = [ + "itoa", + "serde", +] + [[package]] name = "serde_repr" version = "0.1.11" @@ -663,17 +1129,48 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "siphasher" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + [[package]] name = "smallvec" -version = "1.10.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] [[package]] name = "string_cache" @@ -688,6 +1185,12 @@ dependencies = [ "precomputed-hash", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "syn" version = "1.0.109" @@ -710,6 +1213,42 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "tapi" +version = "0.1.0" +dependencies = [ + "axum", + "dyn-clone", + "futures-util", + "heck", + "indexmap 2.2.3", + "itertools 0.12.1", + "openapiv3", + "serde", + "serde_json", + "tapi-macro", + "tsify", +] + +[[package]] +name = "tapi-macro" +version = "0.1.0" +dependencies = [ + "darling", + "heck", + "prettyplease", + "proc-macro2", + "quote", + "serde_derive_internals 0.29.0", + "syn 2.0.48", +] + [[package]] name = "term" version = "0.7.0" @@ -765,6 +1304,120 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tsify" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b26cf145f2f3b9ff84e182c448eaf05468e247f148cf3d2a7d67d78ff023a0" +dependencies = [ + "gloo-utils", + "serde", + "serde_json", + "tsify-macros", + "wasm-bindgen", +] + +[[package]] +name = "tsify-macros" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a94b0f0954b3e59bfc2c246b4c8574390d94a4ad4ad246aaf2fb07d7dfd3b47" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals 0.28.0", + "syn 2.0.48", +] + [[package]] name = "unicode-bidi" version = "0.3.11" @@ -810,7 +1463,7 @@ version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b208a50ff438dcdc887ea3f2db59530bd2f4bc3d2c70630e4d7ee7a281a1d1b" dependencies = [ - "indexmap 2.0.0", + "indexmap 2.2.3", "serde", "serde_json", "utoipa-gen", @@ -895,6 +1548,16 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +[[package]] +name = "web-sys" +version = "0.3.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33b99f4b23ba3eec1a53ac264e35a755f00e966e0065077d6027c0f575b0b97" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" @@ -935,6 +1598,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.3", +] + [[package]] name = "windows-targets" version = "0.42.1" @@ -965,6 +1637,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d380ba1dc7187569a8a9e91ed34b8ccfc33123bbacb8c0aed2d1ad7f3ef2dc5f" +dependencies = [ + "windows_aarch64_gnullvm 0.52.3", + "windows_aarch64_msvc 0.52.3", + "windows_i686_gnu 0.52.3", + "windows_i686_msvc 0.52.3", + "windows_x86_64_gnu 0.52.3", + "windows_x86_64_gnullvm 0.52.3", + "windows_x86_64_msvc 0.52.3", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" @@ -977,6 +1664,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e5dcfb9413f53afd9c8f86e56a7b4d86d9a2fa26090ea2dc9e40fba56c6ec6" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" @@ -989,6 +1682,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dab469ebbc45798319e69eebf92308e541ce46760b49b18c6b3fe5e8965b30f" + [[package]] name = "windows_i686_gnu" version = "0.42.1" @@ -1001,6 +1700,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a4e9b6a7cac734a8b4138a4e1044eac3404d8326b6c0f939276560687a033fb" + [[package]] name = "windows_i686_msvc" version = "0.42.1" @@ -1013,6 +1718,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b0ec9c422ca95ff34a78755cfa6ad4a51371da2a5ace67500cf7ca5f232c58" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" @@ -1025,6 +1736,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704131571ba93e89d7cd43482277d6632589b18ecf4468f591fbae0a8b101614" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" @@ -1037,6 +1754,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42079295511643151e98d61c38c0acc444e52dd42ab456f7ccfd5152e8ecf21c" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" @@ -1048,3 +1771,9 @@ name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0770833d60a970638e989b3fa9fd2bb1aaadcf88963d1659fd7d9990196ed2d6" diff --git a/crates/optics/Cargo.toml b/crates/optics/Cargo.toml index f0c05efe..44398469 100644 --- a/crates/optics/Cargo.toml +++ b/crates/optics/Cargo.toml @@ -11,6 +11,7 @@ once_cell = { workspace = true } itertools = { workspace = true } logos = { workspace = true } serde = { workspace = true } +tapi = { workspace = true } utoipa = { workspace = true } [build-dependencies] diff --git a/crates/optics/src/lib.rs b/crates/optics/src/lib.rs index 09bb2d55..d4b32c11 100644 --- a/crates/optics/src/lib.rs +++ b/crates/optics/src/lib.rs @@ -367,7 +367,7 @@ impl Display for Rule { } } -#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone, ToSchema)] +#[derive(Debug, PartialEq, Default, Serialize, Deserialize, Clone, ToSchema, tapi::Tapi)] #[serde(rename_all = "camelCase")] pub struct HostRankings { pub liked: Vec,