enum_impl/
enum_impl.rs

1use arrow::array::*;
2use arrow_message::prelude::*;
3
4#[derive(Debug)]
5enum Encoding {
6    RGB8,
7    RGBA8,
8    BGR8,
9    BGRA8,
10}
11
12impl Encoding {
13    pub fn into_string(self) -> String {
14        match self {
15            Encoding::RGB8 => "RGB8".to_string(),
16            Encoding::RGBA8 => "RGBA8".to_string(),
17            Encoding::BGR8 => "BGR8".to_string(),
18            Encoding::BGRA8 => "BGRA8".to_string(),
19        }
20    }
21
22    pub fn try_from_string(value: String) -> arrow::error::Result<Self> {
23        match value.as_str() {
24            "RGB8" => Ok(Encoding::RGB8),
25            "RGBA8" => Ok(Encoding::RGBA8),
26            "BGR8" => Ok(Encoding::BGR8),
27            "BGRA8" => Ok(Encoding::BGRA8),
28            _ => Err(arrow::error::ArrowError::ParseError(format!(
29                "Invalid encoding: {}",
30                value
31            ))),
32        }
33    }
34}
35
36impl ArrowMessage for Encoding {
37    fn field(name: impl Into<String>) -> Field {
38        String::field(name)
39    }
40
41    fn try_from_arrow(data: ArrayData) -> arrow::error::Result<Self> {
42        Encoding::try_from_string(String::try_from_arrow(data)?)
43    }
44
45    fn try_into_arrow(self) -> arrow::error::Result<ArrayRef> {
46        String::try_into_arrow(self.into_string())
47    }
48}
49
50impl TryFrom<ArrayData> for Encoding {
51    type Error = arrow::error::ArrowError;
52
53    fn try_from(data: ArrayData) -> arrow::error::Result<Self> {
54        Encoding::try_from_arrow(data)
55    }
56}
57
58impl TryFrom<Encoding> for ArrayData {
59    type Error = arrow::error::ArrowError;
60
61    fn try_from(metadata: Encoding) -> arrow::error::Result<Self> {
62        metadata.try_into_arrow().map(|array| array.into_data())
63    }
64}
65
66#[derive(Debug)]
67struct Metadata {
68    name: Option<String>,
69    width: u32,
70    height: u32,
71    encoding: Encoding,
72}
73
74impl ArrowMessage for Metadata {
75    fn field(name: impl Into<String>) -> Field {
76        make_union_fields(
77            name,
78            vec![
79                Option::<String>::field("name"),
80                Option::<u32>::field("width"),
81                Option::<u32>::field("height"),
82                Encoding::field("encoding"),
83            ],
84        )
85    }
86
87    fn try_from_arrow(data: arrow::array::ArrayData) -> arrow::error::Result<Self>
88    where
89        Self: Sized,
90    {
91        let (map, children) = unpack_union(data);
92
93        Ok(Metadata {
94            name: extract_union_data("name", &map, &children)?,
95            width: extract_union_data("width", &map, &children)?,
96            height: extract_union_data("height", &map, &children)?,
97            encoding: extract_union_data("encoding", &map, &children)?,
98        })
99    }
100
101    fn try_into_arrow(self) -> arrow::error::Result<arrow::array::ArrayRef> {
102        let union_fields = get_union_fields::<Self>()?;
103
104        make_union_array(
105            union_fields,
106            vec![
107                self.name.try_into_arrow()?,
108                self.width.try_into_arrow()?,
109                self.height.try_into_arrow()?,
110                self.encoding.try_into_arrow()?,
111            ],
112        )
113    }
114}
115
116impl TryFrom<ArrayData> for Metadata {
117    type Error = arrow::error::ArrowError;
118
119    fn try_from(data: ArrayData) -> arrow::error::Result<Self> {
120        Metadata::try_from_arrow(data)
121    }
122}
123
124impl TryFrom<Metadata> for ArrayData {
125    type Error = arrow::error::ArrowError;
126
127    fn try_from(metadata: Metadata) -> arrow::error::Result<Self> {
128        metadata.try_into_arrow().map(|array| array.into_data())
129    }
130}
131
132#[derive(Debug)]
133struct Image {
134    data: UInt8Array,
135    metadata: Option<Metadata>,
136}
137
138impl ArrowMessage for Image {
139    fn field(name: impl Into<String>) -> Field {
140        make_union_fields(
141            name,
142            vec![
143                UInt8Array::field("data"),
144                Option::<Metadata>::field("metadata"),
145            ],
146        )
147    }
148
149    fn try_from_arrow(data: arrow::array::ArrayData) -> arrow::error::Result<Self>
150    where
151        Self: Sized,
152    {
153        let (map, children) = unpack_union(data);
154
155        Ok(Image {
156            data: extract_union_data("data", &map, &children)?,
157            metadata: extract_union_data("metadata", &map, &children)?,
158        })
159    }
160
161    fn try_into_arrow(self) -> arrow::error::Result<arrow::array::ArrayRef> {
162        let union_fields = get_union_fields::<Self>()?;
163
164        make_union_array(
165            union_fields,
166            vec![self.data.try_into_arrow()?, self.metadata.try_into_arrow()?],
167        )
168    }
169}
170
171impl TryFrom<ArrayData> for Image {
172    type Error = arrow::error::ArrowError;
173
174    fn try_from(data: ArrayData) -> arrow::error::Result<Self> {
175        Image::try_from_arrow(data)
176    }
177}
178
179impl TryFrom<Image> for ArrayData {
180    type Error = arrow::error::ArrowError;
181
182    fn try_from(image: Image) -> arrow::error::Result<Self> {
183        image.try_into_arrow().map(|array| array.into_data())
184    }
185}
186
187fn main() -> arrow::error::Result<()> {
188    let image = Image {
189        data: UInt8Array::from(vec![1, 2, 3]),
190        metadata: Some(Metadata {
191            name: Some("example".to_string()),
192            width: 12,
193            height: 12,
194            encoding: Encoding::RGB8,
195        }),
196    };
197
198    println!("{:?}", image);
199
200    let arrow = ArrayData::try_from(image)?;
201    let image = Image::try_from(arrow)?;
202
203    println!("{:?}", image);
204
205    Ok(())
206}