add napi schema

This commit is contained in:
Namekuji 2023-06-02 06:22:09 -04:00
parent d0734ef4c9
commit e51deb3794
No known key found for this signature in database
GPG key ID: B541BD6E646CABC7
10 changed files with 83 additions and 7 deletions

View file

@ -7,6 +7,7 @@ edition = "2021"
[features] [features]
default = [] default = []
noarray = [] noarray = []
napi = ["dep:napi", "dep:napi-derive"]
[dependencies] [dependencies]
async-trait = "0.1.68" async-trait = "0.1.68"
@ -25,3 +26,7 @@ thiserror = "1.0.40"
tokio = { version = "1.28.1", features = ["sync"] } tokio = { version = "1.28.1", features = ["sync"] }
util = { path = "../util" } util = { path = "../util" }
utoipa = "3.3.0" utoipa = "3.3.0"
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
napi = { version = "2.12.0", default-features = false, features = ["napi4"], optional = true }
napi-derive = { version = "2.12.0", optional = true }

View file

@ -1,9 +1,10 @@
use async_trait::async_trait; use async_trait::async_trait;
use cfg_if::cfg_if;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use crate::entity::{antenna, antenna_note, user_group_joining}; use crate::entity::{antenna, antenna_note, user_group_joining};
use crate::error::Error; use crate::error::Error;
use crate::schema::antenna::Antenna; use crate::schema::Antenna;
use super::macros::impl_pack_by_id; use super::macros::impl_pack_by_id;
use super::Repository; use super::Repository;
@ -27,9 +28,17 @@ impl Repository<Antenna> for antenna::Model {
Some(m) => Some(m.user_group_id), Some(m) => Some(m.user_group_id),
}; };
cfg_if! {
if #[cfg(feature = "napi")] {
let created_at: String = self.created_at.to_rfc3339();
} else {
let created_at: chrono::DateTime<chrono::Utc> = self.created_at.into();
}
}
Ok(Antenna { Ok(Antenna {
id: self.id, id: self.id,
created_at: self.created_at.into(), created_at,
name: self.name, name: self.name,
keywords: self.keywords.into(), keywords: self.keywords.into(),
exclude_keywords: self.exclude_keywords.into(), exclude_keywords: self.exclude_keywords.into(),

View file

@ -1,9 +1,21 @@
pub mod antenna; pub mod antenna;
pub mod app; pub mod app;
use cfg_if::cfg_if;
use jsonschema::JSONSchema; use jsonschema::JSONSchema;
use schemars::{schema_for, JsonSchema}; use schemars::{schema_for, JsonSchema};
cfg_if! {
if #[cfg(feature = "napi")] {
mod napi;
pub use napi::antenna::Antenna;
pub use napi::antenna::AntennaSrc;
} else {
pub use antenna::Antenna;
pub use antenna::AntennaSrc;
}
}
/// Structs of schema defitions implement this trait in order to /// Structs of schema defitions implement this trait in order to
/// provide the JSON Schema validator [`jsonschema::JSONSchema`]. /// provide the JSON Schema validator [`jsonschema::JSONSchema`].
pub trait Schema<T: JsonSchema> { pub trait Schema<T: JsonSchema> {

View file

@ -47,10 +47,10 @@ pub enum AntennaSrc {
} }
impl TryFrom<AntennaSrcEnum> for AntennaSrc { impl TryFrom<AntennaSrcEnum> for AntennaSrc {
type Error = parse_display::ParseError; type Error = crate::error::Error;
fn try_from(value: AntennaSrcEnum) -> Result<Self, Self::Error> { fn try_from(value: AntennaSrcEnum) -> Result<Self, Self::Error> {
value.to_string().parse() value.to_string().parse().map_err(crate::error::Error::from)
} }
} }
@ -63,7 +63,7 @@ pub static VALIDATOR: Lazy<JSONSchema> = Lazy::new(|| Antenna::validator());
mod unit_test { mod unit_test {
use serde_json::json; use serde_json::json;
use crate::{entity::sea_orm_active_enums::AntennaSrcEnum, schema::antenna::AntennaSrc}; use crate::{entity::sea_orm_active_enums::AntennaSrcEnum, schema::AntennaSrc};
use super::VALIDATOR; use super::VALIDATOR;

View file

@ -0,0 +1 @@
pub mod antenna;

View file

@ -0,0 +1,47 @@
use parse_display::FromStr;
use schemars::JsonSchema;
use utoipa::ToSchema;
use napi::bindgen_prelude::{FromNapiValue, ToNapiValue};
use napi_derive::napi;
#[napi]
#[derive(Clone, Debug, PartialEq, Eq, JsonSchema, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct Antenna {
pub id: String,
pub created_at: String,
pub name: String,
pub keywords: Vec<Vec<String>>,
pub exclude_keywords: Vec<Vec<String>>,
#[schema(inline)]
pub src: AntennaSrc,
pub user_list_id: Option<String>,
pub user_group_id: Option<String>,
pub users: Vec<String>,
pub instances: Vec<String>,
#[serde(default)]
pub case_sensitive: bool,
#[serde(default)]
pub notify: bool,
#[serde(default)]
pub with_replies: bool,
#[serde(default)]
pub with_file: bool,
#[serde(default)]
pub has_unread_note: bool,
}
#[napi]
#[derive(Debug, FromStr, PartialEq, Eq, JsonSchema, ToSchema)]
#[serde(rename_all = "camelCase")]
#[display(style = "camelCase")]
#[display("'{}'")]
pub enum AntennaSrc {
Home,
All,
Users,
List,
Group,
Instances,
}

View file

@ -1,3 +1,5 @@
#![cfg(not(feature = "napi"))]
extern crate model; extern crate model;
mod repository; mod repository;

View file

@ -33,7 +33,7 @@ mod int_test {
.await .await
.expect("Unable to pack"); .expect("Unable to pack");
let result = schema::antenna::Antenna { let result = schema::Antenna {
id: alice_antenna.id, id: alice_antenna.id,
created_at: alice_antenna.created_at.into(), created_at: alice_antenna.created_at.into(),
name: "Test Antenna".to_string(), name: "Test Antenna".to_string(),
@ -47,7 +47,7 @@ mod int_test {
vec!["def".to_string(), "ghi".to_string()], vec!["def".to_string(), "ghi".to_string()],
] ]
.into(), .into(),
src: schema::antenna::AntennaSrc::All, src: schema::AntennaSrc::All,
user_list_id: None, user_list_id: None,
user_group_id: None, user_group_id: None,
users: vec![].into(), users: vec![].into(),