substrate_data/forms/text/
doc.rs1use super::{LineCol, Spans};
4use crate::model::value::{Path, Seg, Value};
5
6#[derive(Debug, Clone, PartialEq)]
8pub struct Doc {
9 pub value: Value,
11 pub spans: Spans,
13}
14
15impl Doc {
16 pub fn spans_at(&self, path: &Path) -> &Spans {
19 let mut v = &self.value;
20 let mut s = &self.spans;
21 for seg in path.segments() {
22 let i = match (seg, v) {
23 (Seg::Key(k), Value::Map(m)) => m.index_of(k),
24 (Seg::Index(i), Value::List(l)) if *i < l.len() => Some(*i),
25 _ => None,
26 };
27 let Some(i) = i else { break };
28 let Some(child) = s.children.get(i) else {
29 break;
30 };
31 v = match v {
32 Value::Map(m) => m.value_at(i).unwrap_or(v),
33 Value::List(l) => &l[i],
34 _ => v,
35 };
36 s = child;
37 }
38 s
39 }
40
41 pub fn locate(&self, text: &str, path: &Path) -> LineCol {
43 LineCol::of(text, self.spans_at(path).span.start as usize)
44 }
45}