flams_ontology/narration/
paragraphs.rs1use std::{fmt::Display, str::FromStr};
2
3use flams_utils::vecmap::VecMap;
4
5use crate::{
6 content::terms::Term,
7 ftml::FTMLKey,
8 uris::{DocumentElementURI, Name, SymbolURI},
9 Checked, CheckingState, DocumentRange,
10};
11
12use super::{DocumentElement, NarrationTrait};
13
14#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
15#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
16#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
17#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
18pub enum ParagraphFormatting {
19 Block,
20 Inline,
21 Collapsed,
22}
23
24#[derive(Debug)]
25pub struct LogicalParagraph<State: CheckingState> {
26 pub kind: ParagraphKind,
27 pub uri: DocumentElementURI,
28 pub formatting: ParagraphFormatting,
29 pub title: Option<DocumentRange>,
30 pub range: DocumentRange,
31 pub styles: Box<[Name]>,
32 pub children: State::Seq<DocumentElement<State>>,
33 pub fors: VecMap<SymbolURI, Option<Term>>,
34}
35
36crate::serde_impl! {
37 struct LogicalParagraph[kind,uri,formatting,title,range,styles,children,fors]
38}
39
40impl NarrationTrait for LogicalParagraph<Checked> {
41 #[inline]
42 fn children(&self) -> &[DocumentElement<Checked>] {
43 &self.children
44 }
45 #[inline]
46 fn from_element(e: &DocumentElement<Checked>) -> Option<&Self>
47 where
48 Self: Sized,
49 {
50 if let DocumentElement::Paragraph(e) = e {
51 Some(e)
52 } else {
53 None
54 }
55 }
56}
57
58#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
59#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
60#[cfg_attr(feature = "wasm", derive(tsify_next::Tsify))]
61#[cfg_attr(feature = "wasm", tsify(into_wasm_abi, from_wasm_abi))]
62#[non_exhaustive]
63pub enum ParagraphKind {
64 Definition,
65 Assertion,
66 Paragraph,
67 Proof,
68 SubProof,
69 Example,
70}
71
72impl ParagraphKind {
73 const DEF: &str = FTMLKey::Definition.attr_name();
74 const ASS: &str = FTMLKey::Assertion.attr_name();
75 const PAR: &str = FTMLKey::Paragraph.attr_name();
76 const PRO: &str = FTMLKey::Proof.attr_name();
77 const SUB: &str = FTMLKey::SubProof.attr_name();
78 #[must_use]
79 pub fn from_ftml(s: &str) -> Option<Self> {
80 Some(match s {
81 Self::DEF => Self::Definition,
82 Self::ASS => Self::Assertion,
83 Self::PAR => Self::Paragraph,
84 Self::PRO => Self::Proof,
85 Self::SUB => Self::SubProof,
86 _ => return None,
87 })
88 }
89 #[must_use]
90 pub fn is_definition_like(&self, styles: &[Name]) -> bool {
91 match &self {
92 Self::Definition | Self::Assertion => true,
93 _ => styles
94 .iter()
95 .any(|s| s.first_name().as_ref() == "symdoc" || s.first_name().as_ref() == "decl"),
96 }
97 }
98 #[cfg(feature = "rdf")]
99 #[must_use]
100 #[allow(clippy::wildcard_imports)]
101 pub const fn rdf_type(&self) -> crate::rdf::NamedNodeRef {
102 use crate::rdf::ontologies::ulo2::*;
103 match self {
104 Self::Definition => DEFINITION,
105 Self::Assertion => PROPOSITION,
106 Self::Paragraph => PARA,
107 Self::Proof => PROOF,
108 Self::SubProof => SUBPROOF,
109 Self::Example => EXAMPLE,
110 }
111 }
112
113 #[must_use]
114 pub const fn as_str(self) -> &'static str {
115 match self {
116 Self::Definition => "definition",
117 Self::Assertion => "assertion",
118 Self::Paragraph => "paragraph",
119 Self::Proof => "proof",
120 Self::SubProof => "subproof",
121 Self::Example => "example",
122 }
123 }
124
125 #[must_use]
126 pub const fn as_display_str(self) -> &'static str {
127 match self {
128 Self::Definition => "Definition",
129 Self::Assertion => "Assertion",
130 Self::Paragraph => "Paragraph",
131 Self::Proof => "Proof",
132 Self::SubProof => "Subproof",
133 Self::Example => "Example",
134 }
135 }
136}
137impl Display for ParagraphKind {
138 #[inline]
139 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
140 f.write_str(self.as_display_str())
141 }
142}
143impl FromStr for ParagraphKind {
144 type Err = ();
145 #[inline]
146 fn from_str(s: &str) -> Result<Self, Self::Err> {
147 match s.trim() {
148 "definition" => Ok(Self::Definition),
149 "assertion" => Ok(Self::Assertion),
150 "paragraph" => Ok(Self::Paragraph),
151 "proof" => Ok(Self::Proof),
152 "subproof" => Ok(Self::SubProof),
153 "example" => Ok(Self::Example),
154 _ => Err(()),
155 }
156 }
157}