//! Serde model for the subset of the AT Protocol lexicon schema language that //! the codegen understands. Anything it does not understand degrades to //! `serde_json::Value` in the generated code rather than failing. use std::collections::BTreeMap; use serde::Deserialize; #[derive(Debug, Deserialize)] pub struct LexiconDoc { #[allow(dead_code)] pub lexicon: u32, pub id: String, #[serde(default)] pub defs: BTreeMap, } #[derive(Debug, Deserialize)] #[serde(tag = "type", rename_all = "kebab-case")] pub enum LexDef { Record(RecordDef), Query(XrpcDef), Procedure(XrpcDef), Subscription(SubscriptionDef), Object(ObjectDef), Token(TokenDef), /// A def that is a bare non-object type (rare); emitted as a type alias. #[serde(untagged)] Type(LexType), } #[derive(Debug, Deserialize)] pub struct RecordDef { #[serde(default)] pub description: Option, #[allow(dead_code)] #[serde(default)] pub key: Option, pub record: ObjectDef, } #[derive(Debug, Deserialize)] pub struct XrpcDef { #[serde(default)] pub description: Option, #[serde(default)] pub parameters: Option, #[serde(default)] pub input: Option, #[serde(default)] pub output: Option, #[serde(default)] pub errors: Vec, } #[derive(Debug, Deserialize)] pub struct SubscriptionDef { #[serde(default)] pub description: Option, } #[derive(Debug, Deserialize)] pub struct BodyDef { pub encoding: String, #[serde(default)] pub schema: Option, } #[derive(Debug, Deserialize)] pub struct ErrorDef { pub name: String, #[serde(default)] pub description: Option, } #[derive(Debug, Deserialize)] pub struct ParamsDef { #[serde(default)] pub description: Option, #[serde(default)] pub required: Vec, #[serde(default)] pub properties: BTreeMap, } #[derive(Debug, Deserialize)] pub struct ObjectDef { #[serde(default)] pub description: Option, #[serde(default)] pub required: Vec, #[serde(default)] pub nullable: Vec, #[serde(default)] pub properties: BTreeMap, } #[derive(Debug, Deserialize)] pub struct TokenDef { #[serde(default)] pub description: Option, } #[derive(Debug, Deserialize)] #[serde(tag = "type", rename_all = "kebab-case")] pub enum LexType { String { #[serde(default)] description: Option, #[serde(default)] format: Option, #[serde(default, rename = "knownValues")] known_values: Option>, }, Integer { #[serde(default)] description: Option, }, Boolean { #[serde(default)] description: Option, }, Array { #[serde(default)] description: Option, items: Box, }, Object(ObjectDef), Ref { #[serde(rename = "ref")] target: String, }, Union { #[serde(default)] refs: Vec, }, Blob { #[serde(default)] description: Option, }, Unknown { #[serde(default)] description: Option, }, Bytes { #[serde(default)] description: Option, }, CidLink { #[serde(default)] description: Option, }, /// Catch-all for lexicon types the codegen does not model. #[serde(untagged)] Other(serde_json::Value), } impl LexType { pub fn description(&self) -> Option<&str> { match self { LexType::String { description, .. } | LexType::Integer { description } | LexType::Boolean { description } | LexType::Array { description, .. } | LexType::Blob { description } | LexType::Unknown { description } | LexType::Bytes { description } | LexType::CidLink { description } => description.as_deref(), LexType::Object(o) => o.description.as_deref(), _ => None, } } }