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}