message_enum_impl/
message_enum_impl.rs

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