Skip to main content

ordinary_template/
lib.rs

1#![doc = include_str!("../README.md")]
2#![warn(clippy::all, clippy::pedantic)]
3#![allow(clippy::missing_errors_doc, clippy::cast_sign_loss)]
4
5// Copyright (C) 2026 Ordinary Labs, LLC.
6//
7// SPDX-License-Identifier: AGPL-3.0-only
8
9mod ffi;
10
11use anyhow::bail;
12use bytes::Bytes;
13use flexbuffers::VectorReader;
14use hashbrown::HashMap;
15use http::{HeaderName, HeaderValue, StatusCode};
16use parking_lot::RwLock;
17use std::collections::BTreeMap;
18use std::str::FromStr;
19use std::sync::Arc;
20use std::time::Duration;
21use tracing::{info_span, instrument};
22
23use ordinary_auth::Auth;
24use ordinary_config::{
25    ContentDefinition, ModelConfig, OrdinaryConfig, QueryExpression, StoredCachePolicy,
26    TemplateConfig, TemplateFfiVersion, TemplateRef, TemplateRefField, TemplateRefFieldBind,
27};
28use ordinary_storage::{ArtifactKind, CacheRead, RefDepth, Storage};
29use ordinary_types::{Field, Kind};
30
31use wasmtime::Module;
32
33pub use wasmtime::Engine;
34
35#[derive(Clone, Debug, PartialEq)]
36pub enum TemplateResult {
37    Result(Bytes),
38    StatusCode(StatusCode),
39}
40
41#[derive(Clone, Debug)]
42enum Include {
43    Field(u8, Kind),
44    Fields(u8, Vec<Include>, bool),
45}
46
47impl Include {
48    fn build_for_field(
49        field: &Field,
50        ref_field: &TemplateRefField,
51        model_map: &HashMap<String, ModelConfig>,
52        ref_depth: &mut RefDepth,
53    ) -> anyhow::Result<Self> {
54        let field_idx = field.idx;
55
56        match &ref_field.fields {
57            Some(nested_ref_fields) => {
58                let mut nested = vec![];
59                let mut is_list = false;
60
61                let mut nested_field_map = HashMap::new();
62
63                match &field.kind {
64                    Kind::List { kind } => {
65                        if let Kind::Object { name: _, fields } = &**kind {
66                            for nested_field in fields {
67                                nested_field_map.insert(nested_field.name.clone(), nested_field);
68                            }
69
70                            is_list = true;
71                        } else {
72                            bail!("cannot have nested fields on non object");
73                        }
74                    }
75                    Kind::Object { name: _, fields } => {
76                        for nested_field in fields {
77                            nested_field_map.insert(nested_field.name.clone(), nested_field);
78                        }
79                    }
80                    Kind::Ref {
81                        model,
82                        field: _,
83                        many: _,
84                    } => {
85                        if let Some(model) = model_map.get(model) {
86                            for nested_field in &model.fields {
87                                nested_field_map.insert(nested_field.name.clone(), nested_field);
88                            }
89
90                            ref_depth.0.push(((field.idx, 1, None), RefDepth(vec![])));
91                        }
92                    }
93                    _ => bail!("cannot have nested fields on non object"),
94                }
95
96                let mut fields_clone = nested_ref_fields.clone();
97                fields_clone.sort_by(|a, b| a.idx.cmp(&b.idx));
98
99                for nested_ref_field in fields_clone {
100                    if let Some(nested_field) = nested_field_map.get(&nested_ref_field.name) {
101                        nested.push(Self::build_for_field(
102                            nested_field,
103                            &nested_ref_field,
104                            model_map,
105                            ref_depth,
106                        )?);
107                    }
108                }
109
110                nested.shrink_to_fit();
111                Ok(Include::Fields(field_idx, nested, is_list))
112            }
113            None => Ok(Include::Field(field_idx, field.kind.clone())),
114        }
115    }
116
117    fn build_for_content(
118        content_def: &ContentDefinition,
119        template_ref: &TemplateRef,
120    ) -> anyhow::Result<Vec<Self>> {
121        let mut include_fields = vec![];
122
123        let mut fields_clone = template_ref.fields.clone();
124        fields_clone.sort_by(|a, b| a.idx.cmp(&b.idx));
125
126        let mut content_def_field_map = HashMap::new();
127        for field in &content_def.fields {
128            content_def_field_map.insert(field.name.clone(), field);
129        }
130
131        for field in fields_clone {
132            if let Some(def_field) = content_def_field_map.get(&field.name) {
133                let include = Self::build_for_field(
134                    def_field,
135                    &field,
136                    &HashMap::new(),
137                    &mut RefDepth(vec![]),
138                )?;
139                include_fields.push(include);
140            }
141        }
142
143        include_fields.shrink_to_fit();
144        Ok(include_fields)
145    }
146
147    fn build_for_model(
148        model_config: &ModelConfig,
149        template_ref: &TemplateRef,
150        model_map: &HashMap<String, ModelConfig>,
151    ) -> anyhow::Result<(Vec<Self>, RefDepth)> {
152        let mut include_fields = vec![];
153
154        let mut fields_clone = template_ref.fields.clone();
155        fields_clone.sort_by(|a, b| a.idx.cmp(&b.idx));
156
157        let mut model_config_field_map = HashMap::new();
158        for field in &model_config.fields {
159            model_config_field_map.insert(field.name.clone(), field);
160        }
161        let mut ref_depth = RefDepth(vec![]);
162
163        for field in fields_clone {
164            if let Some(def_field) = model_config_field_map.get(&field.name) {
165                let include = Self::build_for_field(def_field, &field, model_map, &mut ref_depth)?;
166                include_fields.push(include);
167            }
168        }
169
170        include_fields.shrink_to_fit();
171        Ok((include_fields, ref_depth))
172    }
173
174    fn marry(
175        &self,
176        builder: &mut flexbuffers::VectorBuilder,
177        reader: &VectorReader<&[u8]>,
178    ) -> anyhow::Result<()> {
179        match self {
180            Include::Field(idx, kind) => {
181                kind.copy_to(&reader.idx(*idx as usize), builder, None)?;
182            }
183            Include::Fields(idx, fields, is_list) => {
184                let mut nested = builder.start_vector();
185                let reader = reader.idx(*idx as usize).as_vector();
186
187                if *is_list {
188                    for list_reader in &reader {
189                        let mut builder = nested.start_vector();
190
191                        for field in fields {
192                            field.marry(&mut builder, &list_reader.as_vector())?;
193                        }
194
195                        builder.end_vector();
196                    }
197                } else {
198                    for field in fields {
199                        field.marry(&mut nested, &reader)?;
200                    }
201                }
202
203                nested.end_vector();
204            }
205        }
206
207        Ok(())
208    }
209}
210
211#[derive(Clone, Debug)]
212enum QueryKind {
213    /// path position, whether it's a wildcard
214    Segment(usize, bool),
215    /// token field idx
216    Token(u8),
217    /// if there is no query
218    None,
219}
220
221#[derive(Clone, Debug)]
222enum Query {
223    /// model kind, field idx, type
224    Model(
225        u8,
226        u8,
227        Kind,
228        RefDepth,
229        Option<ordinary_storage::QueryExpression>,
230    ),
231    /// def idx, field idx, type
232    Content(u8, u8, Kind),
233
234    /// def idx
235    ContentMulti(u8),
236}
237
238#[derive(Clone)]
239pub struct Template {
240    pub idx: u8,
241    pub mime: HeaderValue,
242    pub reporting_endpoints: (HeaderName, HeaderValue),
243    pub config: TemplateConfig,
244
245    pub cache_control: Option<String>,
246    pub csp: Arc<RwLock<Option<HeaderValue>>>,
247
248    engine: Engine,
249    module: Arc<RwLock<Option<Module>>>,
250
251    storage: Arc<Storage>,
252
253    queries: Option<Vec<(Query, QueryKind, Vec<Include>)>>,
254}
255
256impl Template {
257    #[allow(clippy::too_many_lines, clippy::too_many_arguments)]
258    #[instrument(
259        name = "template"
260        skip(domain, secure, src, engine, config, auth, storage, model_map, content_map),
261        fields(i, nm),
262        err
263    )]
264    pub fn new(
265        domain: &str,
266        secure: bool,
267
268        src: Option<Bytes>,
269
270        config: TemplateConfig,
271        auth: Arc<Auth>,
272        model_map: &HashMap<String, ModelConfig>,
273        content_map: &HashMap<String, ContentDefinition>,
274
275        engine: Engine,
276        storage: Arc<Storage>,
277    ) -> anyhow::Result<Template> {
278        tracing::Span::current().record("i", config.idx);
279        tracing::Span::current().record("nm", tracing::field::display(&config.name));
280
281        let (module, csp) = if let Some(src) = src {
282            let root = flexbuffers::Reader::get_root(src.as_ref())?;
283            let root_vec = root.as_vector();
284
285            if let Ok(module) = Module::new(&engine, root_vec.idx(1).as_blob().0) {
286                let csp = if matches!(
287                    config.mime.as_str(),
288                    "text/html" | "text/html; charset=utf-8" | "text/xml"
289                ) {
290                    Some(HeaderValue::from_str(root_vec.idx(0).as_str())?)
291                } else {
292                    None
293                };
294
295                (
296                    Arc::new(RwLock::new(Some(module))),
297                    Arc::new(RwLock::new(csp)),
298                )
299            } else {
300                (Arc::new(RwLock::new(None)), Arc::new(RwLock::new(None)))
301            }
302        } else {
303            (Arc::new(RwLock::new(None)), Arc::new(RwLock::new(None)))
304        };
305
306        tracing::info!("init");
307
308        let mut queries = vec![];
309
310        // todo: disallow conflicting bindings
311
312        if let Some(content_refs) = &config.content {
313            for content_ref in content_refs {
314                if let Some(content_def) = content_map.get(&content_ref.name) {
315                    let mut def_fields_map = BTreeMap::new();
316
317                    for field in &content_def.fields {
318                        def_fields_map.insert(field.name.clone(), field);
319                    }
320
321                    let include_fields = Include::build_for_content(content_def, content_ref)?;
322
323                    if content_ref.all.is_some() {
324                        queries.push((
325                            content_ref.idx,
326                            Query::ContentMulti(content_def.idx),
327                            QueryKind::None,
328                            include_fields.clone(),
329                        ));
330                    }
331
332                    for ref_field in &content_ref.fields {
333                        if let Some(def_field) = def_fields_map.get(&ref_field.name)
334                            && let Some(binding) = &ref_field.bind
335                        {
336                            match binding {
337                                TemplateRefFieldBind::Segment {
338                                    name,
339                                    expression: _,
340                                } => {
341                                    let mut path_pos = None;
342
343                                    for (i, segment) in config.route.split('/').enumerate() {
344                                        if segment == format!("{{{name}}}") {
345                                            path_pos = Some((i, name.starts_with('*')));
346                                        }
347                                    }
348
349                                    if let Some((path_pos, is_wildcard)) = path_pos {
350                                        queries.push((
351                                            content_ref.idx,
352                                            Query::Content(
353                                                content_def.idx,
354                                                def_field.idx,
355                                                def_field.kind.clone(),
356                                            ),
357                                            QueryKind::Segment(path_pos, is_wildcard),
358                                            include_fields.clone(),
359                                        ));
360                                    } else {
361                                        bail!(
362                                            "cannot bind to segment {{{name}}} as it is not present in the route"
363                                        );
364                                    }
365                                }
366                                TemplateRefFieldBind::Token {
367                                    field,
368                                    expression: _,
369                                } => {
370                                    let mut auth_field_idx = None;
371
372                                    for auth_field in &auth.config.access_token.claims {
373                                        if &auth_field.name == field {
374                                            auth_field_idx = Some(auth_field.idx);
375                                        }
376                                    }
377
378                                    if let Some(idx) = auth_field_idx {
379                                        queries.push((
380                                            content_ref.idx,
381                                            Query::Content(
382                                                content_def.idx,
383                                                def_field.idx,
384                                                def_field.kind.clone(),
385                                            ),
386                                            QueryKind::Token(idx),
387                                            include_fields.clone(),
388                                        ));
389                                    } else {
390                                        bail!("auth field {field} does not exist");
391                                    }
392                                }
393                            }
394                        }
395                    }
396                }
397            }
398        }
399
400        if let Some(model_refs) = &config.models {
401            for model_ref in model_refs {
402                if let Some(model_config) = model_map.get(&model_ref.name) {
403                    let mut model_config_fields_map = BTreeMap::new();
404
405                    let mut model_config = (*model_config).clone();
406
407                    let uuid_field = Field {
408                        idx: 0,
409                        name: "uuid".into(),
410                        kind: Kind::Uuid,
411                        indexed: Some(true),
412                        queryable: None,
413                        searchable: None,
414                        mapping: None,
415                        doc: None,
416                        encrypted: None,
417                        compressed: None,
418                    };
419
420                    let mut new_fields = model_config.fields.clone();
421                    new_fields.splice(0..0, vec![uuid_field]);
422
423                    model_config.fields = new_fields;
424
425                    for field in &model_config.fields {
426                        model_config_fields_map.insert(field.name.clone(), field);
427                    }
428
429                    let (include_fields, ref_depth) =
430                        Include::build_for_model(&model_config, model_ref, model_map)?;
431
432                    for ref_field in &model_ref.fields {
433                        if let Some(config_field) = model_config_fields_map.get(&ref_field.name)
434                            && let Some(binding) = &ref_field.bind
435                        {
436                            match binding {
437                                TemplateRefFieldBind::Segment { name, expression } => {
438                                    let mut path_pos = None;
439
440                                    for (i, segment) in config.route.split('/').enumerate() {
441                                        if segment == format!("{{{name}}}") {
442                                            path_pos = Some((i, name.starts_with('*')));
443                                        }
444                                    }
445
446                                    let exp = match expression {
447                                        Some(exp) => match exp {
448                                            QueryExpression::Gte => {
449                                                Some(ordinary_storage::QueryExpression::Gte)
450                                            }
451                                            QueryExpression::Lte => {
452                                                Some(ordinary_storage::QueryExpression::Lte)
453                                            }
454                                            QueryExpression::Gt => {
455                                                Some(ordinary_storage::QueryExpression::Gt)
456                                            }
457                                            QueryExpression::Lt => {
458                                                Some(ordinary_storage::QueryExpression::Lt)
459                                            }
460                                            QueryExpression::Eq => {
461                                                Some(ordinary_storage::QueryExpression::Eq)
462                                            }
463                                            QueryExpression::BeginsWith => {
464                                                Some(ordinary_storage::QueryExpression::BeginsWith)
465                                            }
466                                        },
467                                        None => None,
468                                    };
469
470                                    if let Some((path_pos, is_wildcard)) = path_pos {
471                                        queries.push((
472                                            model_ref.idx,
473                                            Query::Model(
474                                                model_config.idx,
475                                                config_field.idx,
476                                                config_field.kind.clone(),
477                                                ref_depth.clone(),
478                                                exp,
479                                            ),
480                                            QueryKind::Segment(path_pos, is_wildcard),
481                                            include_fields.clone(),
482                                        ));
483                                    } else {
484                                        bail!(
485                                            "cannot bind to segment {{{name}}} as it is not present in the route"
486                                        );
487                                    }
488                                }
489                                TemplateRefFieldBind::Token { field, expression } => {
490                                    let mut auth_field_idx = None;
491
492                                    for auth_field in &auth.config.access_token.claims {
493                                        if &auth_field.name == field {
494                                            auth_field_idx = Some(auth_field.idx);
495                                        }
496                                    }
497
498                                    let exp = match expression {
499                                        Some(exp) => match exp {
500                                            QueryExpression::Gte => {
501                                                Some(ordinary_storage::QueryExpression::Gte)
502                                            }
503                                            QueryExpression::Lte => {
504                                                Some(ordinary_storage::QueryExpression::Lte)
505                                            }
506                                            QueryExpression::Gt => {
507                                                Some(ordinary_storage::QueryExpression::Gt)
508                                            }
509                                            QueryExpression::Lt => {
510                                                Some(ordinary_storage::QueryExpression::Lt)
511                                            }
512                                            QueryExpression::Eq => {
513                                                Some(ordinary_storage::QueryExpression::Eq)
514                                            }
515                                            QueryExpression::BeginsWith => {
516                                                Some(ordinary_storage::QueryExpression::BeginsWith)
517                                            }
518                                        },
519                                        None => None,
520                                    };
521
522                                    if let Some(idx) = auth_field_idx {
523                                        queries.push((
524                                            model_ref.idx,
525                                            Query::Model(
526                                                model_config.idx,
527                                                config_field.idx,
528                                                config_field.kind.clone(),
529                                                ref_depth.clone(),
530                                                exp,
531                                            ),
532                                            QueryKind::Token(idx),
533                                            include_fields.clone(),
534                                        ));
535                                    } else {
536                                        bail!("auth field {field} does not exist");
537                                    }
538                                }
539                            }
540                        }
541                    }
542                }
543            }
544        }
545
546        let mut cache_control = String::new();
547
548        if let Some(cache) = &config.cache
549            && let Some(http_cache) = &cache.http
550            && let Some(http_cache_control) = &http_cache.cache_control
551        {
552            // todo: make the default configurable by the API server
553            http_cache_control.header_value(&mut cache_control, "")?;
554        } else {
555            // todo: set a default for the cache control (dictated by Ordinary API Server)
556        }
557
558        let reporting_endpoints = format!(
559            "csp=\"http{}://{domain}/reports/csp\"",
560            if secure { "s" } else { "" }
561        );
562
563        Ok(Template {
564            idx: config.idx,
565            mime: HeaderValue::from_str(config.mime.as_str())?,
566            reporting_endpoints: (
567                HeaderName::from_static("reporting-endpoints"),
568                HeaderValue::from_str(reporting_endpoints.as_str())?,
569            ),
570
571            config,
572
573            cache_control: if cache_control.is_empty() {
574                None
575            } else {
576                Some(cache_control)
577            },
578
579            csp,
580
581            engine,
582            module,
583            storage,
584
585            queries: if queries.is_empty() {
586                None
587            } else {
588                queries.sort_by(|a, b| a.0.cmp(&b.0));
589                let mut queries = queries
590                    .iter()
591                    .map(|(_, q, qk, i)| (q.clone(), qk.clone(), i.clone()))
592                    .collect::<Vec<_>>();
593
594                queries.shrink_to_fit();
595
596                Some(queries)
597            },
598        })
599    }
600
601    pub fn start_tasks(&self) {
602        if let Some(cache_config) = &self.config.cache
603            && let Some(stored_cache) = &cache_config.stored
604        {
605            let storage_clone = self.storage.clone();
606            let storage_clone2 = self.storage.clone();
607
608            let cache_config_clone = stored_cache.clone();
609            let idx = self.config.idx;
610
611            let template_span =
612                info_span!("template", i = &self.config.idx, nm = %self.config.name);
613
614            let cache_span = template_span.in_scope(|| info_span!("cache"));
615            let cache_span_clone = cache_span.clone();
616
617            // todo: pass this default and a range check from Ordinary API
618            let (mut sync_min, mut sync_max) =
619                cache_config_clone.sync_interval.unwrap_or((60, 60 * 3));
620
621            sync_min *= 1000;
622            sync_max *= 1000;
623
624            tokio::spawn(async move {
625                loop {
626                    // todo: break on app kill
627
628                    let cache_sync_interval_ms = rand::random_range(sync_min..sync_max);
629
630                    tokio::time::sleep(Duration::from_millis(cache_sync_interval_ms)).await;
631
632                    cache_span.in_scope(|| {
633                        if let Err(err) = storage_clone.cache.sync(&CacheRead::Template, idx) {
634                            tracing::error!(%err, "failed to sync cache");
635                        }
636                    });
637                }
638            });
639
640            if let StoredCachePolicy::Permanent = stored_cache.policy {
641                // don't start the cache_clean task
642            } else {
643                // todo: pass this default and a range check from Ordinary API
644                let (mut clean_min, mut clean_max) =
645                    cache_config_clone.clean_interval.unwrap_or((60, 60 * 3));
646
647                clean_min *= 1000;
648                clean_max *= 1000;
649
650                tokio::spawn(async move {
651                    loop {
652                        // todo: break on app kill
653
654                        let cache_clean_interval_ms = rand::random_range(clean_min..clean_max);
655
656                        tokio::time::sleep(Duration::from_millis(cache_clean_interval_ms)).await;
657
658                        cache_span_clone.in_scope(|| {
659                            if let Err(err) = storage_clone2.cache.clean_cache(
660                                &CacheRead::Template,
661                                &cache_config_clone,
662                                idx,
663                            ) {
664                                tracing::error!(%err, "failed to clean cache");
665                            }
666                        });
667                    }
668                });
669            }
670        }
671    }
672
673    #[instrument(skip(self, src, app_config, csp_style, csp_script, secure), err)]
674    pub fn set_wasm(
675        &self,
676        src: &[u8],
677        app_config: &OrdinaryConfig,
678        csp_style: Option<Vec<String>>,
679        csp_script: Option<Vec<String>>,
680        secure: bool,
681    ) -> anyhow::Result<()> {
682        let storage_span = info_span!("storage");
683        let span = storage_span.in_scope(|| info_span!("artifact"));
684
685        let csp_string = self.config.csp.clone().unwrap_or_default().build_string(
686            &app_config.csp.clone().unwrap_or_default(),
687            csp_style,
688            csp_script,
689            secure,
690        );
691
692        let mut builder = flexbuffers::Builder::new(&flexbuffers::BuilderOptions::SHARE_NONE);
693        let mut builder_vec = builder.start_vector();
694
695        builder_vec.push(csp_string.as_str());
696        builder_vec.push(flexbuffers::Blob(src));
697
698        builder_vec.end_vector();
699
700        span.in_scope(|| {
701            self.storage
702                .artifact
703                .put(self.idx, ArtifactKind::Template, builder.view())
704        })?;
705
706        let mut lock = self.module.write();
707        let module = Module::new(&self.engine, src)?;
708
709        *lock = Some(module);
710        drop(lock);
711
712        if let Ok(mime) = self.mime.to_str()
713            && matches!(mime, "text/html" | "text/html; charset=utf-8" | "text/xml")
714        {
715            let mut lock = self.csp.write();
716
717            *lock = Some(HeaderValue::from_str(csp_string.as_str())?);
718            drop(lock);
719        }
720
721        let span = storage_span.in_scope(|| info_span!("cache"));
722
723        span.in_scope(|| {
724            self.storage
725                .cache
726                .artifact_evict(CacheRead::Template, self.idx)
727        })?;
728
729        Ok(())
730    }
731
732    #[instrument(skip(self, path, params, error, totp, claims), err)]
733    pub fn render(
734        &self,
735        host: &str,
736        path: String,
737        params: Option<String>,
738        // message and code
739        error: Option<(String, u16)>,
740        // svg qr_code, account and recovery_codes
741        totp: Option<(String, String, String)>,
742        claims: &Option<VectorReader<&[u8]>>,
743    ) -> anyhow::Result<TemplateResult> {
744        let args = self.query(host, path, params, error, totp, claims)?;
745
746        match self.config.ffi.version {
747            TemplateFfiVersion::V1 => ffi::v1::call(self, &args),
748        }
749    }
750
751    // accepts token + bound arguments and then uses config to go request all the stuff
752    #[allow(clippy::too_many_lines)]
753    #[instrument(skip(self, path, params, error, totp, claims), err)]
754    pub fn query(
755        &self,
756        host: &str,
757        path: String,
758        params: Option<String>,
759        // message and code
760        error: Option<(String, u16)>,
761        // svg qr_code, account and recovery_codes
762        totp: Option<(String, String, String)>,
763        claims: &Option<VectorReader<&[u8]>>,
764    ) -> anyhow::Result<Bytes> {
765        let mut builder = flexbuffers::Builder::new(&flexbuffers::BuilderOptions::SHARE_NONE);
766        let mut vec_builder = builder.start_vector();
767
768        if let Some(queries) = &self.queries {
769            let segments: Vec<&str> = path.split('/').collect();
770
771            let _params_map = match params {
772                Some(_params) => {
773                    let params_map: BTreeMap<String, String> = BTreeMap::new();
774                    // todo: update params map
775                    Some(params_map)
776                }
777                None => None,
778            };
779
780            // todo: push params into
781
782            // todo: push flags into
783
784            for (query, query_kind, includes) in queries {
785                let kind = match query {
786                    Query::Model(_, _, kind, _, _) | Query::Content(_, _, kind) => kind,
787                    Query::ContentMulti(_) => &Kind::Void,
788                };
789
790                let indexed_val: Bytes = match query_kind {
791                    QueryKind::Segment(pos, is_wildcard) => {
792                        if pos <= &segments.len() {
793                            let val = if *is_wildcard {
794                                let mut out = String::new();
795
796                                for (i, segment) in segments.iter().enumerate() {
797                                    if i == *pos {
798                                        (*segment).clone_into(&mut out);
799                                    } else if i > *pos {
800                                        out = format!("{out}/{segment}");
801                                    }
802                                }
803
804                                out
805                            } else {
806                                segments[*pos].to_string()
807                            };
808
809                            match kind {
810                                Kind::Uuid => {
811                                    let uuid = uuid::Uuid::from_str(&val)?;
812                                    Bytes::copy_from_slice(uuid.as_bytes())
813                                }
814                                _ => Bytes::copy_from_slice(val.as_bytes()),
815                            }
816                        } else {
817                            bail!("position out of bounds for route");
818                        }
819                    }
820                    QueryKind::Token(field_idx) => {
821                        if let Some(claims) = claims {
822                            let reader = claims.idx(*field_idx as usize);
823
824                            match kind {
825                                Kind::Uuid => Bytes::copy_from_slice(reader.as_blob().0),
826                                Kind::String => Bytes::copy_from_slice(reader.as_str().as_bytes()),
827                                _ => Bytes::new(),
828                            }
829                        } else {
830                            bail!("no claims on query");
831                        }
832                    }
833                    QueryKind::None => Bytes::new(),
834                };
835
836                let span = info_span!("storage");
837
838                match query {
839                    Query::Content(def_idx, field_idx, _kind) => {
840                        let content_obj = span.in_scope(|| {
841                            let content_span = info_span!("content");
842
843                            content_span.in_scope(|| {
844                                self.storage.content.get(*def_idx, *field_idx, &indexed_val)
845                            })
846                        })?;
847
848                        let root = flexbuffers::Reader::get_root(&content_obj[..])?;
849
850                        let mut fields_builder = vec_builder.start_vector();
851
852                        for include in includes {
853                            include.marry(&mut fields_builder, &root.as_vector())?;
854                        }
855
856                        fields_builder.end_vector();
857                    }
858                    Query::ContentMulti(def_idx) => {
859                        let content_objs = span.in_scope(|| {
860                            let content_span = info_span!("content");
861
862                            content_span.in_scope(|| self.storage.content.list(*def_idx))
863                        })?;
864
865                        let root = flexbuffers::Reader::get_root(&content_objs[..])?;
866
867                        let mut object_vector = vec_builder.start_vector();
868
869                        for object in &root.as_vector() {
870                            let obj_bytes = object.as_blob().0;
871
872                            let object = flexbuffers::Reader::get_root(obj_bytes)?;
873
874                            let mut fields_builder = object_vector.start_vector();
875
876                            for include in includes {
877                                include.marry(&mut fields_builder, &object.as_vector())?;
878                            }
879
880                            fields_builder.end_vector();
881                        }
882
883                        object_vector.end_vector();
884                    }
885                    Query::Model(model_kind, field_idx, _kind, ref_depth, expression) => {
886                        if let Some(exp) = expression {
887                            let items = span.in_scope(|| {
888                                self.storage.model.query_model(
889                                    *model_kind,
890                                    *field_idx,
891                                    exp.as_byte(),
892                                    &indexed_val,
893                                    ref_depth,
894                                    None,
895                                )
896                            })?;
897
898                            let root = flexbuffers::Reader::get_root(&items[..])?;
899
900                            let mut item_builder = vec_builder.start_vector();
901
902                            for item in &root.as_vector() {
903                                let mut fields_builder = item_builder.start_vector();
904
905                                for include in includes {
906                                    include.marry(&mut fields_builder, &item.as_vector())?;
907                                }
908
909                                fields_builder.end_vector();
910                            }
911
912                            item_builder.end_vector();
913                        } else {
914                            let model_item = span.in_scope(|| {
915                                self.storage.model.get_model(
916                                    *model_kind,
917                                    *field_idx,
918                                    &indexed_val,
919                                    ref_depth,
920                                    None,
921                                )
922                            })?;
923
924                            let root = flexbuffers::Reader::get_root(&model_item[..])?;
925
926                            let mut fields_builder = vec_builder.start_vector();
927
928                            for include in includes {
929                                include.marry(&mut fields_builder, &root.as_vector())?;
930                            }
931
932                            fields_builder.end_vector();
933                        }
934                    }
935                }
936            }
937        }
938
939        if let Some(error) = error {
940            let mut error_builder = vec_builder.start_vector();
941
942            error_builder.push(error.0.as_str());
943            error_builder.push(error.1);
944
945            error_builder.end_vector();
946        }
947
948        if let Some(totp) = totp {
949            let mut totp_builder = vec_builder.start_vector();
950
951            totp_builder.push(totp.0.as_str());
952            totp_builder.push(totp.1.as_str());
953
954            let mut recovery_codes_vec = totp_builder.start_vector();
955
956            let mut chunk = String::new();
957
958            for (i, c) in totp.2.chars().enumerate() {
959                if i != 0 && i % 11 == 0 {
960                    recovery_codes_vec.push(chunk.as_str());
961                    chunk = String::new();
962                } else {
963                    chunk = format!("{chunk}{c}");
964                }
965            }
966
967            recovery_codes_vec.end_vector();
968
969            totp_builder.end_vector();
970        }
971
972        vec_builder.push(host);
973        vec_builder.end_vector();
974
975        Ok(Bytes::copy_from_slice(builder.view()))
976    }
977}