tellers_timeline_core/
metadata.rs1use crate::{Clip, Gap, Item, MediaReference, Stack, Timeline, Track};
2
3pub trait IdMetadataExt {
4 fn get_id(&self) -> Option<String>;
5 fn set_id(&mut self, id: Option<String>);
6}
7
8fn read_id_from_metadata(meta: &serde_json::Value) -> Option<String> {
9 meta.get("tellers.ai")
10 .and_then(|v| v.get("timeline_id"))
11 .and_then(|v| v.as_str())
12 .map(|s| s.to_string())
13}
14
15pub(crate) fn write_id_to_metadata(meta: &mut serde_json::Value, id: Option<String>) {
16 if meta.as_object().is_none() {
18 *meta = serde_json::Value::Object(serde_json::Map::new());
19 }
20
21 let map = meta.as_object_mut().unwrap();
22 match id {
23 Some(uid) => {
24 let ai_entry = map
26 .entry("tellers.ai".to_string())
27 .or_insert_with(|| serde_json::Value::Object(serde_json::Map::new()));
28 if ai_entry.as_object().is_none() {
29 *ai_entry = serde_json::Value::Object(serde_json::Map::new());
30 }
31 let ai_map = ai_entry.as_object_mut().unwrap();
32 ai_map.insert("timeline_id".to_string(), serde_json::Value::String(uid));
33 }
34 None => {
35 if let Some(ai_entry) = map.get_mut("tellers.ai") {
36 if let Some(ai_map) = ai_entry.as_object_mut() {
37 ai_map.remove("timeline_id");
38 }
40 }
41 }
42 }
43}
44
45impl IdMetadataExt for Clip {
46 fn get_id(&self) -> Option<String> {
47 read_id_from_metadata(&self.metadata)
48 }
49 fn set_id(&mut self, id: Option<String>) {
50 write_id_to_metadata(&mut self.metadata, id)
51 }
52}
53
54impl IdMetadataExt for Track {
55 fn get_id(&self) -> Option<String> {
56 read_id_from_metadata(&self.metadata)
57 }
58 fn set_id(&mut self, id: Option<String>) {
59 write_id_to_metadata(&mut self.metadata, id)
60 }
61}
62
63impl IdMetadataExt for Gap {
64 fn get_id(&self) -> Option<String> {
65 read_id_from_metadata(&self.metadata)
66 }
67 fn set_id(&mut self, id: Option<String>) {
68 write_id_to_metadata(&mut self.metadata, id)
69 }
70}
71
72impl IdMetadataExt for Item {
73 fn get_id(&self) -> Option<String> {
74 match self {
75 Item::Clip(c) => c.get_id(),
76 Item::Gap(g) => g.get_id(),
77 }
78 }
79 fn set_id(&mut self, id: Option<String>) {
80 match self {
81 Item::Clip(c) => c.set_id(id),
82 Item::Gap(g) => g.set_id(id),
83 }
84 }
85}
86
87pub trait MetadataExt {
88 fn get_metadata(&self) -> &serde_json::Value;
89 fn get_metadata_mut(&mut self) -> &mut serde_json::Value;
90 fn set_metadata(&mut self, metadata: serde_json::Value);
91}
92
93impl MetadataExt for Timeline {
94 fn get_metadata(&self) -> &serde_json::Value {
95 &self.metadata
96 }
97 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
98 &mut self.metadata
99 }
100 fn set_metadata(&mut self, metadata: serde_json::Value) {
101 let mut v = metadata;
102 if v.as_object().is_none() {
103 v = serde_json::Value::Object(serde_json::Map::new());
104 }
105 self.metadata = v;
106 }
107}
108
109impl MetadataExt for Stack {
110 fn get_metadata(&self) -> &serde_json::Value {
111 &self.metadata
112 }
113 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
114 &mut self.metadata
115 }
116 fn set_metadata(&mut self, metadata: serde_json::Value) {
117 let mut v = metadata;
118 if v.as_object().is_none() {
119 v = serde_json::Value::Object(serde_json::Map::new());
120 }
121 self.metadata = v;
122 }
123}
124
125impl MetadataExt for Track {
126 fn get_metadata(&self) -> &serde_json::Value {
127 &self.metadata
128 }
129 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
130 &mut self.metadata
131 }
132 fn set_metadata(&mut self, metadata: serde_json::Value) {
133 let mut v = metadata;
134 if v.as_object().is_none() {
135 v = serde_json::Value::Object(serde_json::Map::new());
136 }
137 self.metadata = v;
138 }
139}
140
141impl MetadataExt for Clip {
142 fn get_metadata(&self) -> &serde_json::Value {
143 &self.metadata
144 }
145 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
146 &mut self.metadata
147 }
148 fn set_metadata(&mut self, metadata: serde_json::Value) {
149 let mut v = metadata;
150 if v.as_object().is_none() {
151 v = serde_json::Value::Object(serde_json::Map::new());
152 }
153 self.metadata = v;
154 }
155}
156
157impl MetadataExt for Gap {
158 fn get_metadata(&self) -> &serde_json::Value {
159 &self.metadata
160 }
161 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
162 &mut self.metadata
163 }
164 fn set_metadata(&mut self, metadata: serde_json::Value) {
165 let mut v = metadata;
166 if v.as_object().is_none() {
167 v = serde_json::Value::Object(serde_json::Map::new());
168 }
169 self.metadata = v;
170 }
171}
172
173impl MetadataExt for MediaReference {
174 fn get_metadata(&self) -> &serde_json::Value {
175 self.metadata()
176 }
177 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
178 self.metadata_mut()
179 }
180 fn set_metadata(&mut self, metadata: serde_json::Value) {
181 let mut v = metadata;
182 if v.as_object().is_none() {
183 v = serde_json::Value::Object(serde_json::Map::new());
184 }
185 *self.metadata_mut() = v;
186 }
187}
188
189impl MetadataExt for Item {
190 fn get_metadata(&self) -> &serde_json::Value {
191 match self {
192 Item::Clip(c) => &c.metadata,
193 Item::Gap(g) => &g.metadata,
194 }
195 }
196 fn get_metadata_mut(&mut self) -> &mut serde_json::Value {
197 match self {
198 Item::Clip(c) => &mut c.metadata,
199 Item::Gap(g) => &mut g.metadata,
200 }
201 }
202 fn set_metadata(&mut self, metadata: serde_json::Value) {
203 let mut v = metadata;
204 if v.as_object().is_none() {
205 v = serde_json::Value::Object(serde_json::Map::new());
206 }
207 match self {
208 Item::Clip(c) => c.metadata = v,
209 Item::Gap(g) => g.metadata = v,
210 }
211 }
212}
213
214pub fn item_link_group_id(item: &Item) -> Option<i64> {
229 match item {
230 Item::Clip(clip) => clip.sync_clips_id(),
231 Item::Gap(_) => None,
232 }
233}
234
235pub fn item_tellers_group_id(item: &Item) -> Option<i64> {
237 match item {
238 Item::Clip(clip) => resolve_tellers_group_id(&clip.metadata),
239 Item::Gap(_) => None,
240 }
241}
242
243pub fn set_item_tellers_group_id(item: &mut Item, group_id: Option<i64>) {
245 let metadata = item.get_metadata_mut();
246 match group_id {
247 Some(group_id) => set_tellers_group_id(metadata, group_id),
248 None => {
249 remove_tellers_group_id(metadata);
250 }
251 }
252}
253
254pub fn resolve_tellers_group_id(metadata: &serde_json::Value) -> Option<i64> {
260 let raw = metadata
261 .get("tellers.ai")
262 .and_then(|v| v.get("Tellers Group ID"))?;
263 raw.as_i64()
264 .or_else(|| raw.as_u64().and_then(|value| i64::try_from(value).ok()))
265 .or_else(|| raw.as_str().and_then(|value| value.parse::<i64>().ok()))
266}
267
268pub fn set_tellers_group_id(metadata: &mut serde_json::Value, group_id: i64) {
271 if metadata.as_object().is_none() {
272 *metadata = serde_json::Value::Object(serde_json::Map::new());
273 }
274 let map = metadata.as_object_mut().unwrap();
275 let ai = map
276 .entry("tellers.ai".to_string())
277 .or_insert_with(|| serde_json::Value::Object(serde_json::Map::new()));
278 if ai.as_object().is_none() {
279 *ai = serde_json::Value::Object(serde_json::Map::new());
280 }
281 ai.as_object_mut().unwrap().insert(
282 "Tellers Group ID".to_string(),
283 serde_json::Value::Number(serde_json::Number::from(group_id)),
284 );
285}
286
287pub fn remove_tellers_group_id(metadata: &mut serde_json::Value) -> bool {
290 let Some(ai) = metadata
291 .get_mut("tellers.ai")
292 .and_then(|value| value.as_object_mut())
293 else {
294 return false;
295 };
296 ai.remove("Tellers Group ID").is_some()
297}