1#![warn(missing_docs)]
13
14use std::collections::BTreeMap;
15
16pub use ytsaurus_skiff::Format as SkiffFormat;
17pub use ytsaurus_yson::YsonFormat;
18
19use ytsaurus_yson::{YsonNode, YsonValue};
20
21#[derive(Debug, Clone, PartialEq, Eq)]
29#[non_exhaustive]
30pub enum DataFormat {
31 Yson(YsonFormat),
33 Skiff(SkiffFormat),
35}
36
37impl DataFormat {
38 #[must_use]
40 pub const fn binary_yson() -> Self {
41 Self::Yson(YsonFormat::Binary)
42 }
43
44 #[must_use]
46 pub const fn text_yson() -> Self {
47 Self::Yson(YsonFormat::Text)
48 }
49
50 #[must_use]
52 pub const fn yson(format: YsonFormat) -> Self {
53 Self::Yson(format)
54 }
55
56 #[must_use]
58 pub fn skiff(format: SkiffFormat) -> Self {
59 Self::Skiff(format)
60 }
61
62 #[must_use]
64 pub const fn as_yson(&self) -> Option<YsonFormat> {
65 match self {
66 Self::Yson(format) => Some(*format),
67 Self::Skiff(_) => None,
68 }
69 }
70
71 #[must_use]
73 pub const fn as_skiff(&self) -> Option<&SkiffFormat> {
74 match self {
75 Self::Yson(_) => None,
76 Self::Skiff(format) => Some(format),
77 }
78 }
79
80 #[must_use]
83 pub fn to_yson(&self) -> YsonValue {
84 match self {
85 Self::Yson(format) => yson_format(*format),
86 Self::Skiff(format) => format.to_yson(),
87 }
88 }
89}
90
91fn yson_format(format: YsonFormat) -> YsonValue {
92 let spelling = match format {
93 YsonFormat::Binary => b"binary".as_slice(),
94 YsonFormat::Text => b"text".as_slice(),
95 };
96 let mut attributes = BTreeMap::new();
97 attributes.insert(
98 b"format".to_vec(),
99 YsonValue {
100 attributes: None,
101 node: YsonNode::String(spelling.to_vec()),
102 },
103 );
104 YsonValue {
105 attributes: Some(attributes),
106 node: YsonNode::String(b"yson".to_vec()),
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use ytsaurus_skiff::{Schema, SchemaRef, WireType};
113
114 use super::*;
115
116 #[test]
117 fn yson_variants_render_the_cluster_declarations() {
118 assert_eq!(
119 ytsaurus_yson::to_string(&DataFormat::binary_yson().to_yson(), YsonFormat::Text)
120 .unwrap(),
121 "<format=binary>yson"
122 );
123 assert_eq!(
124 ytsaurus_yson::to_string(&DataFormat::text_yson().to_yson(), YsonFormat::Text).unwrap(),
125 "<format=text>yson"
126 );
127 }
128
129 #[test]
130 fn skiff_variant_delegates_to_the_validated_format() {
131 let skiff = SkiffFormat::new(vec![SchemaRef::Inline(Schema::tuple([Schema::named(
132 "value",
133 WireType::String32,
134 )]))])
135 .unwrap();
136 let format = DataFormat::skiff(skiff.clone());
137
138 assert_eq!(format.as_yson(), None);
139 assert_eq!(format.as_skiff(), Some(&skiff));
140 assert_eq!(format.to_yson(), skiff.to_yson());
141 }
142}