1use core::{fmt, ops::Deref, str::FromStr};
2
3#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
4#[serde(transparent)]
5pub struct Text(String);
6
7#[derive(Clone, Copy, Debug, Eq, PartialEq, thiserror::Error)]
8#[error("text is empty")]
9pub struct Error;
10
11pub type Result<T, E = Error> = core::result::Result<T, E>;
12
13impl Text {
14 #[inline]
15 pub fn new(text: impl AsRef<str>) -> Result<Self> {
16 let text = text.as_ref().trim();
17 (!text.is_empty()).then(|| Self(text.to_string())).ok_or(Error)
18 }
19
20 pub fn merge(&mut self, text: &Text) {
21 self.0.push_str("\n\n");
22 self.0.push_str(&text.0);
23 }
24}
25
26impl FromStr for Text {
27 type Err = Error;
28
29 #[inline]
30 fn from_str(text: &str) -> Result<Self> {
31 Self::new(text)
32 }
33}
34
35impl AsRef<str> for Text {
36 fn as_ref(&self) -> &str {
37 &self.0
38 }
39}
40
41impl fmt::Display for Text {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 self.0.fmt(f)
44 }
45}
46
47impl Deref for Text {
48 type Target = str;
49
50 fn deref(&self) -> &Self::Target {
51 &self.0
52 }
53}