oca_ast_semantics/ast/
recursive_attributes.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::error::Error;

use recursion::{Collapsible, Expandable, MappableFrame, PartiallyApplied};

use super::{AttributeType, NestedAttrType, RefValue};

/// This module includes structures for setting up the recursion crate. They
/// enable usage of `expand_frames` and `collapse_frames` functions for
/// NestedAttrType.
pub enum NestedAttrTypeFrame<A> {
    Reference(RefValue),
    Value(AttributeType),
    Array(A),
    Null,
}

impl MappableFrame for NestedAttrTypeFrame<PartiallyApplied> {
    type Frame<X> = NestedAttrTypeFrame<X>;

    fn map_frame<A, B>(input: Self::Frame<A>, mut f: impl FnMut(A) -> B) -> Self::Frame<B> {
        match input {
            NestedAttrTypeFrame::Reference(reference) => NestedAttrTypeFrame::Reference(reference),
            NestedAttrTypeFrame::Value(val) => NestedAttrTypeFrame::Value(val),
            NestedAttrTypeFrame::Array(t) => NestedAttrTypeFrame::Array(f(t)),
            NestedAttrTypeFrame::Null => NestedAttrTypeFrame::Null,
        }
    }
}

impl Expandable for NestedAttrType {
    type FrameToken = NestedAttrTypeFrame<PartiallyApplied>;

    fn from_frame(val: <Self::FrameToken as MappableFrame>::Frame<Self>) -> Self {
        match val {
            NestedAttrTypeFrame::Reference(reference) => NestedAttrType::Reference(reference),
            NestedAttrTypeFrame::Value(v) => NestedAttrType::Value(v),
            NestedAttrTypeFrame::Array(arr) => NestedAttrType::Array(Box::new(arr)),
            NestedAttrTypeFrame::Null => NestedAttrType::Null,
        }
    }
}

impl Collapsible for NestedAttrType {
    type FrameToken = NestedAttrTypeFrame<PartiallyApplied>;

    fn into_frame(self) -> <Self::FrameToken as MappableFrame>::Frame<Self> {
        match self {
            NestedAttrType::Reference(reference) => NestedAttrTypeFrame::Reference(reference),
            NestedAttrType::Value(val) => NestedAttrTypeFrame::Value(val),
            NestedAttrType::Array(arr) => NestedAttrTypeFrame::Array(*arr),
            NestedAttrType::Null => NestedAttrTypeFrame::Null,
        }
    }
}

pub struct AttributeTypeResult<E: Error>(Result<NestedAttrType, E>);
pub struct AttributeTypeResultFrame<A, E: Error>(Result<NestedAttrTypeFrame<A>, E>);

impl<E: Error> MappableFrame for AttributeTypeResultFrame<PartiallyApplied, E> {
    type Frame<X> = AttributeTypeResultFrame<X, E>;

    fn map_frame<A, B>(input: Self::Frame<A>, f: impl FnMut(A) -> B) -> Self::Frame<B> {
        match input.0 {
            Ok(frame) => AttributeTypeResultFrame(Ok(NestedAttrTypeFrame::map_frame(frame, f))),
            Err(e) => AttributeTypeResultFrame(Err(e)),
        }
    }
}

impl<E: Error> AttributeTypeResult<E> {
    pub fn value(self) -> Result<NestedAttrType, E> {
        self.0
    }
}

impl<E: Error> Expandable for AttributeTypeResult<E> {
    type FrameToken = AttributeTypeResultFrame<PartiallyApplied, E>;

    fn from_frame(val: <Self::FrameToken as MappableFrame>::Frame<Self>) -> Self {
        let val = match val.0 {
            Ok(NestedAttrTypeFrame::Value(v)) => Ok(NestedAttrType::Value(v)),
            Ok(NestedAttrTypeFrame::Reference(r)) => Ok(NestedAttrType::Reference(r)),
            Ok(NestedAttrTypeFrame::Array(v)) => match v.0 {
                Ok(ok) => Ok(NestedAttrType::Array(Box::new(ok))),
                Err(er) => Err(er),
            },
            Ok(NestedAttrTypeFrame::Null) => Ok(NestedAttrType::Null),
            Err(er) => Err(er),
        };
        Self(val)
    }
}

impl<E: Error> From<E> for AttributeTypeResult<E> {
    fn from(value: E) -> Self {
        AttributeTypeResult(Err(value))
    }
}

impl<A, E: Error> From<E> for AttributeTypeResultFrame<A, E> {
    fn from(value: E) -> Self {
        AttributeTypeResultFrame(Err(value))
    }
}

impl<A, E: Error> From<NestedAttrTypeFrame<A>> for AttributeTypeResultFrame<A, E> {
    fn from(value: NestedAttrTypeFrame<A>) -> Self {
        AttributeTypeResultFrame(Ok(value))
    }
}