nurtex_protocol/types/
text_component.rs1use nurtex_codec::Buffer;
2
3#[derive(Debug, Clone, PartialEq, PartialOrd)]
5pub struct TextComponent(String);
6
7impl Buffer for TextComponent {
8 fn read_buf(buffer: &mut std::io::Cursor<&[u8]>) -> Option<Self> {
9 Some(Self(String::read_buf(buffer)?))
10 }
11
12 fn write_buf(&self, buffer: &mut impl std::io::Write) -> std::io::Result<()> {
13 self.0.write_buf(buffer)
14 }
15}
16
17impl TextComponent {
18 pub fn text(&self) -> String {
20 if let Ok(json) = serde_json::from_str::<serde_json::Value>(&self.0) {
21 self.extract_text_from_json(&json).unwrap_or(self.clear_text(&self.0))
22 } else {
23 self.clear_text(&self.0)
24 }
25 }
26
27 fn extract_text_from_json(&self, value: &serde_json::Value) -> Option<String> {
29 match value {
30 serde_json::Value::String(s) => Some(self.clear_text(s)),
31 serde_json::Value::Object(obj) => {
32 let mut result = String::new();
33
34 if let Some(text) = obj.get("text") {
35 if let serde_json::Value::String(s) = text {
36 result.push_str(&self.clear_text(s));
37 }
38 }
39
40 if let Some(extra) = obj.get("extra") {
41 if let serde_json::Value::Array(arr) = extra {
42 for item in arr {
43 result.push_str(&self.extract_text_from_json(item).unwrap_or(String::new()));
44 }
45 }
46 }
47
48 for (key, val) in obj {
49 if key != "text" && key != "extra" && key != "color" && key != "bold" && key != "italic" {
50 if let serde_json::Value::String(s) = val {
51 if !s.is_empty() && key != "clickEvent" && key != "hoverEvent" {
52 result.push_str(&self.clear_text(s));
53 }
54 }
55 }
56 }
57
58 Some(result)
59 }
60 serde_json::Value::Array(arr) => {
61 let mut result = String::new();
62
63 for item in arr {
64 result.push_str(&self.extract_text_from_json(item).unwrap_or(String::new()));
65 }
66
67 Some(result)
68 }
69 _ => None,
70 }
71 }
72
73 fn clear_text(&self, text: &str) -> String {
75 text.chars().filter(|c| !c.is_control() || *c == '\n' || *c == '\t').collect::<String>()
76 }
77}