message_enum_impl/
message_enum_impl.rs

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