diff --git a/packages/backend/native-utils/crates/model/Cargo.toml b/packages/backend/native-utils/crates/model/Cargo.toml index e9a3260c42..c2002443d6 100644 --- a/packages/backend/native-utils/crates/model/Cargo.toml +++ b/packages/backend/native-utils/crates/model/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [features] default = [] noarray = [] +napi = ["dep:napi", "dep:napi-derive"] [dependencies] async-trait = "0.1.68" @@ -25,3 +26,7 @@ thiserror = "1.0.40" tokio = { version = "1.28.1", features = ["sync"] } util = { path = "../util" } 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 } diff --git a/packages/backend/native-utils/crates/model/src/entity/mod.rs b/packages/backend/native-utils/crates/model/src/entity.rs similarity index 100% rename from packages/backend/native-utils/crates/model/src/entity/mod.rs rename to packages/backend/native-utils/crates/model/src/entity.rs diff --git a/packages/backend/native-utils/crates/model/src/repository/mod.rs b/packages/backend/native-utils/crates/model/src/repository.rs similarity index 100% rename from packages/backend/native-utils/crates/model/src/repository/mod.rs rename to packages/backend/native-utils/crates/model/src/repository.rs diff --git a/packages/backend/native-utils/crates/model/src/repository/antenna.rs b/packages/backend/native-utils/crates/model/src/repository/antenna.rs index d3ad6ececb..c8324edd34 100644 --- a/packages/backend/native-utils/crates/model/src/repository/antenna.rs +++ b/packages/backend/native-utils/crates/model/src/repository/antenna.rs @@ -1,9 +1,10 @@ use async_trait::async_trait; +use cfg_if::cfg_if; use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; use crate::entity::{antenna, antenna_note, user_group_joining}; use crate::error::Error; -use crate::schema::antenna::Antenna; +use crate::schema::Antenna; use super::macros::impl_pack_by_id; use super::Repository; @@ -27,9 +28,17 @@ impl Repository for antenna::Model { 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 = self.created_at.into(); + } + } + Ok(Antenna { id: self.id, - created_at: self.created_at.into(), + created_at, name: self.name, keywords: self.keywords.into(), exclude_keywords: self.exclude_keywords.into(), diff --git a/packages/backend/native-utils/crates/model/src/schema/mod.rs b/packages/backend/native-utils/crates/model/src/schema.rs similarity index 75% rename from packages/backend/native-utils/crates/model/src/schema/mod.rs rename to packages/backend/native-utils/crates/model/src/schema.rs index a647510200..78a0887fe4 100644 --- a/packages/backend/native-utils/crates/model/src/schema/mod.rs +++ b/packages/backend/native-utils/crates/model/src/schema.rs @@ -1,9 +1,21 @@ pub mod antenna; pub mod app; +use cfg_if::cfg_if; use jsonschema::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 /// provide the JSON Schema validator [`jsonschema::JSONSchema`]. pub trait Schema { diff --git a/packages/backend/native-utils/crates/model/src/schema/antenna.rs b/packages/backend/native-utils/crates/model/src/schema/antenna.rs index fa7902b924..2f13a563d8 100644 --- a/packages/backend/native-utils/crates/model/src/schema/antenna.rs +++ b/packages/backend/native-utils/crates/model/src/schema/antenna.rs @@ -47,10 +47,10 @@ pub enum AntennaSrc { } impl TryFrom for AntennaSrc { - type Error = parse_display::ParseError; + type Error = crate::error::Error; fn try_from(value: AntennaSrcEnum) -> Result { - value.to_string().parse() + value.to_string().parse().map_err(crate::error::Error::from) } } @@ -63,7 +63,7 @@ pub static VALIDATOR: Lazy = Lazy::new(|| Antenna::validator()); mod unit_test { 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; diff --git a/packages/backend/native-utils/crates/model/src/schema/napi.rs b/packages/backend/native-utils/crates/model/src/schema/napi.rs new file mode 100644 index 0000000000..16130e4ccd --- /dev/null +++ b/packages/backend/native-utils/crates/model/src/schema/napi.rs @@ -0,0 +1 @@ +pub mod antenna; diff --git a/packages/backend/native-utils/crates/model/src/schema/napi/antenna.rs b/packages/backend/native-utils/crates/model/src/schema/napi/antenna.rs new file mode 100644 index 0000000000..cfba50d7f6 --- /dev/null +++ b/packages/backend/native-utils/crates/model/src/schema/napi/antenna.rs @@ -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>, + pub exclude_keywords: Vec>, + #[schema(inline)] + pub src: AntennaSrc, + pub user_list_id: Option, + pub user_group_id: Option, + pub users: Vec, + pub instances: Vec, + #[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, +} diff --git a/packages/backend/native-utils/crates/model/tests/common.rs b/packages/backend/native-utils/crates/model/tests/common.rs index add8c12b24..554a8ca735 100644 --- a/packages/backend/native-utils/crates/model/tests/common.rs +++ b/packages/backend/native-utils/crates/model/tests/common.rs @@ -1,3 +1,5 @@ +#![cfg(not(feature = "napi"))] + extern crate model; mod repository; diff --git a/packages/backend/native-utils/crates/model/tests/repository/antenna.rs b/packages/backend/native-utils/crates/model/tests/repository/antenna.rs index 193efcba2b..90732130a9 100644 --- a/packages/backend/native-utils/crates/model/tests/repository/antenna.rs +++ b/packages/backend/native-utils/crates/model/tests/repository/antenna.rs @@ -33,7 +33,7 @@ mod int_test { .await .expect("Unable to pack"); - let result = schema::antenna::Antenna { + let result = schema::Antenna { id: alice_antenna.id, created_at: alice_antenna.created_at.into(), name: "Test Antenna".to_string(), @@ -47,7 +47,7 @@ mod int_test { vec!["def".to_string(), "ghi".to_string()], ] .into(), - src: schema::antenna::AntennaSrc::All, + src: schema::AntennaSrc::All, user_list_id: None, user_group_id: None, users: vec![].into(),