1use ftml_ontology::narrative::elements::SectionLevel;
2use ftml_uris::{DocumentElementUri, DocumentUri, FtmlUri, Uri};
3
4pub struct FtmlBackend;
5impl ftml_backend::GlobalBackend for FtmlBackend {
6 type Error = <Self::Backend as ftml_backend::FtmlBackend>::Error; #[cfg(feature = "ssr")]
8 type Backend = Self;
9 #[cfg(all(feature = "hydrate", not(feature = "ssr")))]
10 type Backend = ftml_backend::CachedBackend<Self>;
11 #[inline]
12 fn get() -> &'static Self::Backend {
13 #[cfg(feature = "ssr")]
14 static SLF: FtmlBackend = FtmlBackend;
15 #[cfg(all(feature = "hydrate", not(feature = "ssr")))]
16 static SLF: std::sync::LazyLock<ftml_backend::CachedBackend<FtmlBackend>> =
17 std::sync::LazyLock::new(|| ftml_backend::CachedBackend::new(FtmlBackend));
18 &SLF
19 }
20}
21impl ftml_backend::FlamsBackend for FtmlBackend {
22 #[inline]
23 fn stripped(&self) -> bool {
24 true
25 }
26 fn document_link_url(&self, uri: &ftml_uris::DocumentUri) -> String {
27 format!("/?uri={}", uri.url_encoded())
28 }
29 fn resource_link_url(
30 &self,
31 uri: &ftml_uris::DocumentUri,
32 kind: &'static str,
33 ) -> Option<String> {
34 Some(format!("/doc?uri={}&format={kind}", uri.url_encoded()))
35 }
36
37 fn check_term(
38 &self,
39 global_context: &[ftml_uris::ModuleUri],
40 in_term: either::Either<&ftml_ontology::terms::Term, &DocumentElementUri>,
41 subterm: either::Either<
42 &ftml_ontology::terms::Term,
43 &ftml_ontology::terms::termpaths::TermPath,
44 >,
45 ) -> impl Future<
46 Output = Result<
47 ftml_backend::BackendCheckResult,
48 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
49 >,
50 > + Send
51 + use<> {
52 super::server_fns::check_term(global_context.to_vec(), in_term.cloned(), subterm.cloned())
53 }
54
55 fn get_fragment(
56 &self,
57 uri: Option<ftml_uris::Uri>,
58 rp: Option<String>,
59 a: Option<ftml_uris::ArchiveId>,
60 p: Option<String>,
61 d: Option<String>,
62 m: Option<String>,
63 l: Option<ftml_uris::Language>,
64 e: Option<String>,
65 s: Option<String>,
66 context: Option<ftml_uris::NarrativeUri>,
67 ) -> impl Future<
68 Output = Result<
69 (ftml_uris::Uri, Box<[ftml_ontology::utils::Css]>, Box<str>),
70 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
71 >,
72 >
73 + 'static
74 + use<> {
75 super::server_fns::fragment(uri, rp, a, p, d, m, l, e, s, context)
76 }
77
78 fn get_document_html(
79 &self,
80 uri: Option<ftml_uris::DocumentUri>,
81 rp: Option<String>,
82 a: Option<ftml_uris::ArchiveId>,
83 p: Option<String>,
84 d: Option<String>,
85 l: Option<ftml_uris::Language>,
86 ) -> impl Future<
87 Output = Result<
88 (DocumentUri, Box<[ftml_ontology::utils::Css]>, Box<str>),
89 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
90 >,
91 > + Send
92 + 'static {
93 super::server_fns::document(uri, rp, a, p, d, l)
94 }
95
96 fn get_toc(
97 &self,
98 uri: Option<DocumentUri>,
99 rp: Option<String>,
100 a: Option<ftml_uris::ArchiveId>,
101 p: Option<String>,
102 d: Option<String>,
103 l: Option<ftml_uris::Language>,
104 ) -> impl Future<
105 Output = Result<
106 (
107 Box<[ftml_ontology::utils::Css]>,
108 SectionLevel,
109 Box<[ftml_ontology::narrative::documents::TocElem]>,
110 ),
111 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
112 >,
113 >
114 + 'static
115 + Send {
116 let fut = super::server_fns::toc(uri, rp, a, p, d, l);
117 async move {
118 fut.await
119 .map_err(|e| ftml_backend::BackendError::ToDo(e.to_string()))
120 }
121 }
122
123 fn get_module(
124 &self,
125 uri: Option<ftml_uris::ModuleUri>,
126 a: Option<ftml_uris::ArchiveId>,
127 p: Option<String>,
128 m: Option<String>,
129 ) -> impl Future<
130 Output = Result<
131 ftml_ontology::domain::modules::ModuleLike,
132 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
133 >,
134 > + Send
135 + 'static {
136 super::server_fns::get_module(uri, a, p, m)
137 }
138
139 fn get_solutions(
140 &self,
141 uri: ftml_uris::DocumentElementUri,
142 ) -> impl Future<
143 Output = Result<
144 ftml_ontology::narrative::elements::problems::Solutions,
145 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
146 >,
147 > + Send
148 + 'static {
149 let uriclone = uri.clone();
150 let r = super::server_fns::solution(
151 Some(uri.into()),
152 None,
153 None,
154 None,
155 None,
156 None,
157 None,
158 None,
159 None,
160 );
161 async move {
162 let r = r
163 .await
164 .map_err(|e| ftml_backend::BackendError::ToDo(e.to_string()))?;
165 ftml_ontology::narrative::elements::problems::Solutions::from_jstring(&r)
166 .ok_or_else(|| ftml_backend::BackendError::NotFound(uriclone.into()))
167 }
168 }
169
170 fn get_document(
171 &self,
172 uri: Option<ftml_uris::DocumentUri>,
173 rp: Option<String>,
174 a: Option<ftml_uris::ArchiveId>,
175 p: Option<String>,
176 d: Option<String>,
177 l: Option<ftml_uris::Language>,
178 ) -> impl Future<
179 Output = Result<
180 ftml_ontology::narrative::documents::Document,
181 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
182 >,
183 > + 'static {
184 super::server_fns::get_document(uri, rp, a, p, d, l)
185 }
186
187 fn get_notations(
188 &self,
189 uri: Option<Uri>,
190 rp: Option<String>,
191 a: Option<ftml_uris::ArchiveId>,
192 p: Option<String>,
193 d: Option<String>,
194 m: Option<String>,
195 l: Option<ftml_uris::Language>,
196 e: Option<String>,
197 s: Option<String>,
198 ) -> impl Future<
199 Output = Result<
200 Vec<(
201 ftml_uris::DocumentElementUri,
202 ftml_ontology::narrative::elements::Notation,
203 )>,
204 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
205 >,
206 > + Send
207 + 'static {
208 super::server_fns::notations(uri, rp, a, p, d, m, l, e, s)
209 }
210 fn get_logical_paragraphs(
211 &self,
212 uri: Option<ftml_uris::SymbolUri>,
213 a: Option<ftml_uris::ArchiveId>,
214 p: Option<String>,
215 m: Option<String>,
216 s: Option<String>,
217 problems: bool,
218 ) -> impl Future<
219 Output = Result<
220 Vec<(
221 ftml_uris::DocumentElementUri,
222 ftml_ontology::narrative::elements::ParagraphOrProblemKind,
223 )>,
224 ftml_backend::BackendError<leptos::server_fn::error::ServerFnErrorErr>,
225 >,
226 > + Send
227 + 'static {
228 super::server_fns::los(uri, a, p, m, s, problems)
229 }
230}