1use text_size::TextRange;
2
3use crate::SemanticSnapshot;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum FoldingRangeKind {
14 Namespace,
15 Task,
16}
17
18#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct FoldingRange {
27 pub range: TextRange,
28 pub kind: FoldingRangeKind,
29}
30
31pub fn folding_ranges(snapshot: &SemanticSnapshot) -> Vec<FoldingRange> {
39 let mut ranges = snapshot
40 .document
41 .tasks
42 .iter()
43 .map(|task| FoldingRange {
44 range: task.range,
45 kind: FoldingRangeKind::Task,
46 })
47 .collect::<Vec<_>>();
48
49 for namespace in &snapshot.document.namespaces {
50 let namespace_range = snapshot
51 .document
52 .tasks
53 .iter()
54 .filter(|task| task.namespace.as_deref() == Some(namespace.name.as_str()))
55 .fold(namespace.range, |range, task| {
56 TextRange::new(range.start(), range.end().max(task.range.end()))
57 });
58
59 ranges.push(FoldingRange {
60 range: namespace_range,
61 kind: FoldingRangeKind::Namespace,
62 });
63 }
64
65 ranges
66}