oca_ast_semantics/ast/
recursive_attributes.rs

1use std::error::Error;
2
3use recursion::{Collapsible, Expandable, MappableFrame, PartiallyApplied};
4
5use super::{AttributeType, NestedAttrType, RefValue};
6
7/// This module includes structures for setting up the recursion crate. They
8/// enable usage of `expand_frames` and `collapse_frames` functions for
9/// NestedAttrType.
10pub enum NestedAttrTypeFrame<A> {
11    Reference(RefValue),
12    Value(AttributeType),
13    Array(A),
14    Null,
15}
16
17impl MappableFrame for NestedAttrTypeFrame<PartiallyApplied> {
18    type Frame<X> = NestedAttrTypeFrame<X>;
19
20    fn map_frame<A, B>(input: Self::Frame<A>, mut f: impl FnMut(A) -> B) -> Self::Frame<B> {
21        match input {
22            NestedAttrTypeFrame::Reference(reference) => NestedAttrTypeFrame::Reference(reference),
23            NestedAttrTypeFrame::Value(val) => NestedAttrTypeFrame::Value(val),
24            NestedAttrTypeFrame::Array(t) => NestedAttrTypeFrame::Array(f(t)),
25            NestedAttrTypeFrame::Null => NestedAttrTypeFrame::Null,
26        }
27    }
28}
29
30impl Expandable for NestedAttrType {
31    type FrameToken = NestedAttrTypeFrame<PartiallyApplied>;
32
33    fn from_frame(val: <Self::FrameToken as MappableFrame>::Frame<Self>) -> Self {
34        match val {
35            NestedAttrTypeFrame::Reference(reference) => NestedAttrType::Reference(reference),
36            NestedAttrTypeFrame::Value(v) => NestedAttrType::Value(v),
37            NestedAttrTypeFrame::Array(arr) => NestedAttrType::Array(Box::new(arr)),
38            NestedAttrTypeFrame::Null => NestedAttrType::Null,
39        }
40    }
41}
42
43impl Collapsible for NestedAttrType {
44    type FrameToken = NestedAttrTypeFrame<PartiallyApplied>;
45
46    fn into_frame(self) -> <Self::FrameToken as MappableFrame>::Frame<Self> {
47        match self {
48            NestedAttrType::Reference(reference) => NestedAttrTypeFrame::Reference(reference),
49            NestedAttrType::Value(val) => NestedAttrTypeFrame::Value(val),
50            NestedAttrType::Array(arr) => NestedAttrTypeFrame::Array(*arr),
51            NestedAttrType::Null => NestedAttrTypeFrame::Null,
52        }
53    }
54}
55
56pub struct AttributeTypeResult<E: Error>(Result<NestedAttrType, E>);
57pub struct AttributeTypeResultFrame<A, E: Error>(Result<NestedAttrTypeFrame<A>, E>);
58
59impl<E: Error> MappableFrame for AttributeTypeResultFrame<PartiallyApplied, E> {
60    type Frame<X> = AttributeTypeResultFrame<X, E>;
61
62    fn map_frame<A, B>(input: Self::Frame<A>, f: impl FnMut(A) -> B) -> Self::Frame<B> {
63        match input.0 {
64            Ok(frame) => AttributeTypeResultFrame(Ok(NestedAttrTypeFrame::map_frame(frame, f))),
65            Err(e) => AttributeTypeResultFrame(Err(e)),
66        }
67    }
68}
69
70impl<E: Error> AttributeTypeResult<E> {
71    pub fn value(self) -> Result<NestedAttrType, E> {
72        self.0
73    }
74}
75
76impl<E: Error> Expandable for AttributeTypeResult<E> {
77    type FrameToken = AttributeTypeResultFrame<PartiallyApplied, E>;
78
79    fn from_frame(val: <Self::FrameToken as MappableFrame>::Frame<Self>) -> Self {
80        let val = match val.0 {
81            Ok(NestedAttrTypeFrame::Value(v)) => Ok(NestedAttrType::Value(v)),
82            Ok(NestedAttrTypeFrame::Reference(r)) => Ok(NestedAttrType::Reference(r)),
83            Ok(NestedAttrTypeFrame::Array(v)) => match v.0 {
84                Ok(ok) => Ok(NestedAttrType::Array(Box::new(ok))),
85                Err(er) => Err(er),
86            },
87            Ok(NestedAttrTypeFrame::Null) => Ok(NestedAttrType::Null),
88            Err(er) => Err(er),
89        };
90        Self(val)
91    }
92}
93
94impl<E: Error> From<E> for AttributeTypeResult<E> {
95    fn from(value: E) -> Self {
96        AttributeTypeResult(Err(value))
97    }
98}
99
100impl<A, E: Error> From<E> for AttributeTypeResultFrame<A, E> {
101    fn from(value: E) -> Self {
102        AttributeTypeResultFrame(Err(value))
103    }
104}
105
106impl<A, E: Error> From<NestedAttrTypeFrame<A>> for AttributeTypeResultFrame<A, E> {
107    fn from(value: NestedAttrTypeFrame<A>) -> Self {
108        AttributeTypeResultFrame(Ok(value))
109    }
110}