umya_spreadsheet/structs/
shared_string_item.rs1use super::PhoneticRun;
3use super::RichText;
4use super::Text;
5use super::TextElement;
6use crate::reader::driver::*;
7use crate::writer::driver::*;
8use md5::Digest;
9use quick_xml::events::{BytesStart, Event};
10use quick_xml::Reader;
11use quick_xml::Writer;
12use std::hash::Hasher;
13use std::io::Cursor;
14extern crate ahash;
15use self::ahash::AHasher;
16
17#[derive(Clone, Default, Debug)]
18pub(crate) struct SharedStringItem {
19 text: Option<Text>,
20 rich_text: Option<RichText>,
21}
22
23impl SharedStringItem {
24 #[inline]
25 pub(crate) fn get_text(&self) -> Option<&Text> {
26 self.text.as_ref()
27 }
28
29 #[inline]
30 pub(crate) fn _get_text_mut(&mut self) -> Option<&mut Text> {
31 self.text.as_mut()
32 }
33
34 #[inline]
35 pub(crate) fn set_text(&mut self, value: Text) -> &mut Self {
36 self.text = Some(value);
37 self
38 }
39
40 #[inline]
41 pub(crate) fn _remove_text(&mut self) -> &mut Self {
42 self.text = None;
43 self
44 }
45
46 #[inline]
47 pub(crate) fn get_rich_text(&self) -> Option<&RichText> {
48 self.rich_text.as_ref()
49 }
50
51 #[inline]
52 pub(crate) fn get_rich_text_mut(&mut self) -> Option<&mut RichText> {
53 self.rich_text.as_mut()
54 }
55
56 #[inline]
57 pub(crate) fn set_rich_text(&mut self, value: RichText) -> &mut Self {
58 self.rich_text = Some(value);
59 self
60 }
61
62 #[inline]
63 pub(crate) fn _remove_rich_text(&mut self) -> &mut Self {
64 self.rich_text = None;
65 self
66 }
67
68 pub(crate) fn get_hash_u64(&self) -> u64 {
69 let mut h = AHasher::default();
70 let content = format!(
71 "{}{}",
72 self.text
73 .as_ref()
74 .map_or(String::from("NONE"), |v| v.get_hash_code()),
75 self.rich_text
76 .as_ref()
77 .map_or(String::from("NONE"), |v| v.get_hash_code())
78 );
79 h.write(content.as_bytes());
80 h.finish()
81 }
82
83 pub(crate) fn set_attributes<R: std::io::BufRead>(
84 &mut self,
85 reader: &mut Reader<R>,
86 _e: &BytesStart,
87 ) {
88 let mut vec_text_element: Vec<TextElement> = Vec::new();
89
90 xml_read_loop!(
91 reader,
92 Event::Start(ref e) => {
93 match e.name().into_inner() {
94 b"t" => {
95 let mut obj = Text::default();
96 obj.set_attributes(reader, e);
97 self.set_text(obj);
98 }
99 b"r" => {
100 let mut obj = TextElement::default();
101 obj.set_attributes(reader, e);
102 vec_text_element.push(obj);
103 }
104 b"rPh" => {
105 let mut obj = PhoneticRun::default();
106 obj.set_attributes(reader, e);
107 }
108 _ => (),
109 }
110 },
111 Event::End(ref e) => {
112 if e.name().into_inner() == b"si" {
113 if !vec_text_element.is_empty() {
114 let mut obj = RichText::default();
115 obj.set_rich_text_elements(vec_text_element);
116 self.set_rich_text(obj);
117 }
118 return;
119 }
120 },
121 Event::Eof => panic!("Error: Could not find {} end element", "si")
122 );
123 }
124
125 pub(crate) fn write_to(&self, writer: &mut Writer<Cursor<Vec<u8>>>) {
126 write_start_tag(writer, "si", vec![], false);
128
129 if let Some(v) = &self.text {
131 v.write_to(writer);
132 }
133
134 if let Some(v) = &self.rich_text {
136 v.write_to(writer);
137 }
138
139 write_start_tag(writer, "phoneticPr", vec![("fontId", "1")], true);
140
141 write_end_tag(writer, "si");
142 }
143}