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