Skip to main content

open_timeline_core/
timeline_edit.rs

1// SPDX-License-Identifier: MIT
2
3//!
4//! The OpenTimeline timeline view type
5//!
6
7use crate::{HasIdAndName, Name, OpenTimelineId, ReducedEntities, ReducedTimelines};
8use bool_tag_expr::{BoolTagExpr, Tag, Tags};
9use serde::{Deserialize, Serialize};
10
11/// Represents the information needed for creating and updating a timeline
12///
13/// This is the datastructure used to backup & restore timelines
14#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
15pub struct TimelineEdit {
16    /// The timeline's ID
17    id: Option<OpenTimelineId>,
18
19    /// The timeline's name
20    name: Name,
21
22    /// The timeline's direct `Entity`s
23    bool_expr: Option<BoolTagExpr>,
24
25    /// The timeline's direct `Entity`s
26    entities: Option<ReducedEntities>,
27
28    /// The timeline's direct subtimelines
29    subtimelines: Option<ReducedTimelines>,
30
31    /// The timeline's tags
32    tags: Option<Tags>,
33}
34
35impl TimelineEdit {
36    /// Create a new [`TimelineEdit`]
37    pub fn from(
38        id: Option<OpenTimelineId>,
39        name: Name,
40        bool_expr: Option<BoolTagExpr>,
41        entities: Option<ReducedEntities>,
42        subtimelines: Option<ReducedTimelines>,
43        tags: Option<Tags>,
44    ) -> Result<TimelineEdit, ()> {
45        let mut timeline = TimelineEdit {
46            id,
47            name,
48            bool_expr,
49            entities: None,
50            subtimelines: None,
51            tags: None,
52        };
53
54        // TODO: some validation?
55        timeline.entities = entities;
56        timeline.subtimelines = subtimelines;
57        timeline.tags = tags;
58        Ok(timeline)
59    }
60
61    /// Clear the timeline's ID
62    pub fn clear_id(&mut self) {
63        self.id = None;
64    }
65
66    /// Borrow the timeline's boolean tag expr
67    pub fn bool_expr(&self) -> &Option<BoolTagExpr> {
68        &self.bool_expr
69    }
70
71    /// Clear the timeline's boolean tag expr
72    pub fn clear_bool_expr(&mut self) {
73        self.bool_expr = None;
74    }
75
76    /// Borrow the timeline's entities
77    pub fn entities(&self) -> &Option<ReducedEntities> {
78        &self.entities
79    }
80
81    /// Clear the timeline's entities
82    pub fn clear_entities(&mut self) {
83        self.entities = None;
84    }
85
86    /// Borrow the timeline's subtimelines
87    pub fn subtimelines(&self) -> &Option<ReducedTimelines> {
88        &self.subtimelines
89    }
90
91    /// Clear the timeline's subtimelines
92    pub fn clear_subtimelines(&mut self) {
93        self.subtimelines = None;
94    }
95
96    /// Borrow the timeline's [`Tags`]
97    pub fn tags(&self) -> &Option<Tags> {
98        &self.tags
99    }
100
101    /// Mutably borrow the timeline's [`Tags`]
102    pub fn tags_mut(&mut self) -> &mut Option<Tags> {
103        &mut self.tags
104    }
105
106    /// Add a tag to the timeline
107    pub fn add_tag(&mut self, tag: Tag) {
108        self.tags.get_or_insert_with(Tags::new).insert(tag);
109    }
110
111    /// Remove a tag from the timeline
112    pub fn remove_tag(&mut self, tag: &Tag) {
113        if let Some(tags) = self.tags.as_mut() {
114            tags.remove(tag);
115            if tags.is_empty() {
116                self.tags = None
117            }
118        }
119    }
120
121    /// Set the timeline's [`Tags`]
122    pub fn set_tags(&mut self, tags: Tags) {
123        self.tags = (!tags.is_empty()).then_some(tags);
124    }
125
126    /// Clear the timeline's [`Tags`] and set to `None`
127    pub fn clear_tags(&mut self) {
128        self.tags = None;
129    }
130}
131
132impl HasIdAndName for TimelineEdit {
133    fn id(&self) -> Option<OpenTimelineId> {
134        self.id
135    }
136
137    fn set_id(&mut self, id: OpenTimelineId) {
138        self.id = Some(id)
139    }
140
141    fn name(&self) -> &Name {
142        &self.name
143    }
144
145    fn set_name(&mut self, name: Name) {
146        self.name = name
147    }
148}