mant_protocol/
document.rs1use mant_ir::{
4 Block, Diagnostic, Document as IrDocument, DocumentMeta, DocumentSource, ParserInfo, Section,
5};
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
11pub enum DocumentSchema {
12 #[serde(rename = "mant.document/v0.11")]
14 V0Dot11,
15}
16
17impl DocumentSchema {
18 pub const ID: &'static str = "mant.document/v0.11";
20}
21
22#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
24#[serde(rename_all = "camelCase")]
25pub struct Producer {
26 pub name: String,
28 pub version: String,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub engine: Option<Engine>,
33}
34
35#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
37#[serde(rename_all = "camelCase")]
38pub struct Engine {
39 pub name: String,
41 pub version: String,
43}
44
45#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
47#[serde(rename_all = "camelCase", deny_unknown_fields)]
48pub struct DocumentResponse {
49 pub schema: DocumentSchema,
51 pub producer: Producer,
53 pub source: DocumentSource,
55 pub meta: DocumentMeta,
57 #[serde(default, skip_serializing_if = "Option::is_none")]
59 pub heading: Option<mant_ir::Heading>,
60 #[serde(default, skip_serializing_if = "Vec::is_empty")]
62 pub fragment_aliases: Vec<mant_ir::FragmentAlias>,
63 #[serde(default, skip_serializing_if = "Vec::is_empty")]
65 pub diagnostics: Vec<Diagnostic>,
66 #[serde(default, skip_serializing_if = "Vec::is_empty")]
68 pub blocks: Vec<Block>,
69 pub sections: Vec<Section>,
71}
72
73impl Producer {
74 #[must_use]
76 pub fn for_document(document: &IrDocument) -> Self {
77 Self {
78 name: "mant".to_owned(),
79 version: env!("CARGO_PKG_VERSION").to_owned(),
80 engine: document.parser.as_ref().map(|parser| Engine {
81 name: parser.name.clone(),
82 version: parser.version.clone(),
83 }),
84 }
85 }
86}
87
88impl From<&IrDocument> for DocumentResponse {
89 fn from(document: &IrDocument) -> Self {
90 Self {
91 schema: DocumentSchema::V0Dot11,
92 producer: Producer::for_document(document),
93 source: document.source.clone(),
94 meta: document.meta.clone(),
95 heading: document.heading.clone(),
96 fragment_aliases: document.fragment_aliases.clone(),
97 diagnostics: document.diagnostics.clone(),
98 blocks: document.blocks.clone(),
99 sections: document.sections.clone(),
100 }
101 }
102}
103
104impl From<DocumentResponse> for IrDocument {
105 fn from(document: DocumentResponse) -> Self {
106 Self {
107 parser: document.producer.engine.map(|engine| ParserInfo {
108 name: engine.name,
109 version: engine.version,
110 }),
111 source: document.source,
112 meta: document.meta,
113 heading: document.heading,
114 fragment_aliases: document.fragment_aliases,
115 diagnostics: document.diagnostics,
116 blocks: document.blocks,
117 sections: document.sections,
118 }
119 }
120}