use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct SchemaManifest {
pub name: String,
pub version: String,
pub description: String,
pub when_to_use: String,
#[serde(default)]
pub system_message: Option<String>,
pub types: Vec<String>,
pub relationships: RelationshipVocabulary,
pub community: CommunityConfig,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub default_writing_guidance: Option<DefaultWritingGuidance>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub cross_mem_relationships: Vec<CrossMemRelationshipEntry>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub alias_target_rel_type: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct CrossMemRelationshipEntry {
pub to_schema: String,
pub definitions: Vec<RelationshipDef>,
}
#[derive(Debug, Clone, Default, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct DefaultWritingGuidance {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub avoid: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub goal: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct RelationshipVocabulary {
pub mode: RelationshipMode,
pub definitions: Vec<RelationshipDef>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum RelationshipMode {
Strict,
Open,
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct RelationshipDef {
pub name: String,
pub description: String,
#[serde(default)]
pub when_to_use: Option<String>,
pub default_weight: f32,
#[serde(default)]
pub per_edge_description: PerEdgeDescription,
#[serde(default)]
pub acyclic: bool,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub source_types: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub target_types: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cardinality_per_source: Option<Cardinality>,
#[serde(default)]
pub manual_authoring: ManualAuthoring,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum PerEdgeDescription {
#[default]
Forbidden,
Optional,
Required,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum ManualAuthoring {
#[default]
Allow,
Warn,
Forbidden,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize, JsonSchema)]
pub enum Cardinality {
#[serde(rename = "1")]
One,
#[serde(rename = "0..1")]
ZeroOrOne,
#[serde(rename = "1..N")]
OneOrMore,
#[serde(rename = "0..N")]
ZeroOrMore,
}
impl std::fmt::Display for Cardinality {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Cardinality::One => "1",
Cardinality::ZeroOrOne => "0..1",
Cardinality::OneOrMore => "1..N",
Cardinality::ZeroOrMore => "0..N",
};
f.write_str(s)
}
}
impl Cardinality {
pub fn admits(&self, count: usize) -> bool {
match self {
Cardinality::One => count == 1,
Cardinality::ZeroOrOne => count <= 1,
Cardinality::OneOrMore => count >= 1,
Cardinality::ZeroOrMore => true,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema)]
#[serde(deny_unknown_fields)]
pub struct CommunityConfig {
pub resolution: f64,
pub seed: u32,
}