text_document/
image.rs

1use std::{
2    cell::{Cell, RefCell},
3    rc::{Rc, Weak},
4};
5
6use crate::{
7    format::{FormatChangeResult, IsFormat},
8    ElementUuid,
9};
10use crate::{
11    format::{FormattedElement, ImageFormat},
12    text_document::{Element, ElementManager, ElementTrait, ModelError},
13    Block,
14};
15
16#[derive(Default, Clone, Debug)]
17pub struct Image {
18    uuid: Cell<ElementUuid>,
19    element_manager: Weak<ElementManager>,
20    text: RefCell<String>,
21    image_format: RefCell<ImageFormat>,
22}
23
24impl PartialEq for Image {
25    fn eq(&self, other: &Self) -> bool {
26        self.uuid == other.uuid && self.image_format == other.image_format
27    }
28}
29
30impl Image {
31    pub(crate) fn new(element_manager: Weak<ElementManager>) -> Self {
32        Image {
33            element_manager,
34            uuid: Default::default(),
35            text: RefCell::new("\u{FFFC}".to_string()),
36            ..Default::default()
37        }
38    }
39
40    pub fn uuid(&self) -> ElementUuid {
41        self.uuid.get()
42    }
43
44    pub(crate) fn image_format(&self) -> ImageFormat {
45        self.format()
46    }
47
48    pub fn plain_text(&self) -> String {
49        " ".to_string()
50    }
51
52    pub fn text_length(&self) -> usize {
53        1
54    }
55
56    fn parent_bloc_rc(&self) -> Rc<Block> {
57        let element_manager = self.element_manager.upgrade().unwrap();
58
59        match element_manager
60            .get_parent_element_using_uuid(self.uuid())
61            .unwrap()
62        {
63            Element::BlockElement(block) => block,
64            _ => unreachable!(),
65        }
66    }
67    pub fn position_in_block(&self) -> usize {
68        let parent_block = self.parent_bloc_rc();
69        parent_block.position_of_child(self.uuid())
70    }
71
72    pub fn start(&self) -> usize {
73        let parent_block = self.parent_bloc_rc();
74
75        parent_block.position() + self.position_in_block()
76    }
77
78    pub fn end(&self) -> usize {
79        self.start() + self.text_length()
80    }
81}
82
83impl ElementTrait for Image {
84    fn set_uuid(&self, uuid: usize) {
85        self.uuid.set(uuid);
86    }
87
88    fn verify_rule_with_parent(&self, parent_element: &Element) -> Result<(), ModelError> {
89        match parent_element {
90            Element::FrameElement(_) => Err(ModelError::WrongParent),
91            Element::BlockElement(_) => Ok(()),
92            Element::TextElement(_) => Err(ModelError::WrongParent),
93            Element::ImageElement(_) => Err(ModelError::WrongParent),
94        }
95    }
96}
97
98impl FormattedElement<ImageFormat> for Image {
99    fn format(&self) -> ImageFormat {
100        self.image_format.borrow().clone()
101    }
102
103    fn set_format(&self, format: &ImageFormat) -> FormatChangeResult {
104        if &*self.image_format.borrow() == format {
105            Ok(None)
106        } else {
107            self.image_format.replace(format.clone());
108            Ok(Some(()))
109        }
110    }
111
112    fn merge_format(&self, format: &ImageFormat) -> FormatChangeResult {
113        self.image_format.borrow_mut().merge_with(format)
114    }
115}
116
117#[cfg(test)]
118mod tests {
119
120    use crate::InsertMode;
121
122    use super::*;
123
124    #[test]
125    fn basics() {
126        let image = Image::new(Weak::new());
127
128        assert_eq!(image.uuid(), 0);
129        assert_eq!(image.plain_text(), " ");
130        assert_eq!(image.text_length(), 1);
131        assert_eq!(image.image_format(), ImageFormat::new());
132
133        let image_bis = Image::new(Weak::new());
134
135        assert_eq!(image, image_bis);
136    }
137
138    #[test]
139    fn position() {
140        let element_manager_rc = ElementManager::new_rc();
141        ElementManager::create_root_frame(element_manager_rc.clone());
142
143        let image = element_manager_rc
144            .insert_new_image(1, InsertMode::AsChild)
145            .unwrap();
146
147        assert_eq!(image.parent_bloc_rc().uuid(), 1);
148        assert_eq!(image.start(), 0);
149        assert_eq!(image.end(), 1);
150    }
151}