cranpose_ui/text/
shared_text.rs1use std::{fmt, ops::Deref, rc::Rc};
2
3use super::AnnotatedString;
4use crate::widgets::text::{IntoTextSource, TextSource};
5
6#[derive(Clone, Debug)]
8pub struct SharedText(Storage);
9
10#[derive(Clone, Debug)]
11enum Storage {
12 Static(&'static str),
13 Annotated(Rc<AnnotatedString>),
14}
15
16impl SharedText {
17 pub fn as_str(&self) -> &str {
19 match &self.0 {
20 Storage::Static(text) => text,
21 Storage::Annotated(text) => &text.text,
22 }
23 }
24}
25
26impl PartialEq for SharedText {
27 fn eq(&self, other: &Self) -> bool {
28 match (&self.0, &other.0) {
29 (Storage::Static(a), Storage::Static(b)) => a == b,
30 (Storage::Annotated(a), Storage::Annotated(b)) => Rc::ptr_eq(a, b) || a == b,
31 (Storage::Static(plain), Storage::Annotated(annotated))
32 | (Storage::Annotated(annotated), Storage::Static(plain)) => {
33 *plain == annotated.text
34 && annotated.span_styles.is_empty()
35 && annotated.paragraph_styles.is_empty()
36 && annotated.string_annotations.is_empty()
37 && annotated.link_annotations.is_empty()
38 }
39 }
40 }
41}
42
43impl From<String> for SharedText {
44 fn from(value: String) -> Self {
45 Self(Storage::Annotated(Rc::new(AnnotatedString::from(value))))
46 }
47}
48
49impl From<&'static str> for SharedText {
50 fn from(value: &'static str) -> Self {
51 Self(Storage::Static(value))
52 }
53}
54
55impl From<Rc<AnnotatedString>> for SharedText {
56 fn from(value: Rc<AnnotatedString>) -> Self {
57 Self(Storage::Annotated(value))
58 }
59}
60
61impl From<SharedText> for String {
62 fn from(value: SharedText) -> Self {
63 match value.0 {
64 Storage::Static(text) => text.to_owned(),
65 Storage::Annotated(shared) => match Rc::try_unwrap(shared) {
66 Ok(annotated) => annotated.text,
67 Err(shared) => shared.text.clone(),
68 },
69 }
70 }
71}
72
73impl Deref for SharedText {
74 type Target = str;
75 fn deref(&self) -> &str {
76 self.as_str()
77 }
78}
79
80impl AsRef<str> for SharedText {
81 fn as_ref(&self) -> &str {
82 self.as_str()
83 }
84}
85
86impl fmt::Display for SharedText {
87 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
88 formatter.write_str(self.as_str())
89 }
90}
91
92impl IntoTextSource for SharedText {
93 fn into_text_source(self) -> TextSource {
94 match self.0 {
95 Storage::Static(text) => text.into_text_source(),
96 Storage::Annotated(text) => TextSource::Static(text),
97 }
98 }
99}