diff options
| author | Tert0 <tert0byte@gmail.com> | 2025-10-10 23:19:33 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-10 16:19:33 -0500 |
| commit | 1a1402954b07cd77615d0afc026c73b008787f51 (patch) | |
| tree | 6b0488a0ff5c5bf7b1d90ef349c06fed810532f6 /azalea-chat/src/component.rs | |
| parent | ab507f7ac1c58e96bef26ba1f0e9066a35f841a7 (diff) | |
| download | azalea-drasl-1a1402954b07cd77615d0afc026c73b008787f51.tar.xz | |
Implement primitive translation arguments (#263)
* implement primitive translation arguments
* add distinct number types to PrimitiveOrComponent
* fix deserializing PrimitiveOrComponent::Boolean from nbt
* improve nbt serialization for translatable component arguments
Diffstat (limited to 'azalea-chat/src/component.rs')
| -rw-r--r-- | azalea-chat/src/component.rs | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/azalea-chat/src/component.rs b/azalea-chat/src/component.rs index 338c1def..87886e96 100644 --- a/azalea-chat/src/component.rs +++ b/azalea-chat/src/component.rs @@ -17,7 +17,7 @@ use crate::{ base_component::BaseComponent, style::{ChatFormatting, Style}, text_component::TextComponent, - translatable_component::{StringOrComponent, TranslatableComponent}, + translatable_component::{PrimitiveOrComponent, TranslatableComponent}, }; /// A chat component, basically anything you can see in chat. @@ -306,26 +306,15 @@ impl<'de> Deserialize<'de> for FormattedText { None }; if let Some(with) = json.get("with") { - let with = with + let with_array = with .as_array() - .ok_or_else(|| de::Error::custom("\"with\" must be an array"))?; - let mut with_array = Vec::with_capacity(with.len()); - for item in with { - // if it's a string component with no styling and no siblings, just add a - // string to with_array otherwise add the component - // to the array - let c = FormattedText::deserialize(item).map_err(de::Error::custom)?; - if let FormattedText::Text(text_component) = c - && text_component.base.siblings.is_empty() - && text_component.base.style.is_empty() - { - with_array.push(StringOrComponent::String(text_component.text)); - continue; - } - with_array.push(StringOrComponent::FormattedText( - FormattedText::deserialize(item).map_err(de::Error::custom)?, - )); - } + .ok_or_else(|| de::Error::custom("\"with\" must be an array"))? + .iter() + .map(|item| { + PrimitiveOrComponent::deserialize(item).map_err(de::Error::custom) + }) + .collect::<Result<Vec<PrimitiveOrComponent>, _>>()?; + component = FormattedText::Translatable(TranslatableComponent::with_fallback( translate, fallback, with_array, )); @@ -487,11 +476,11 @@ impl FormattedText { if with_list.empty() { } else if let Some(with) = with_list.strings() { for item in with { - with_array.push(StringOrComponent::String(item.to_string())); + with_array.push(PrimitiveOrComponent::String(item.to_string())); } } else if let Some(with) = with_list.ints() { for item in with { - with_array.push(StringOrComponent::String(item.to_string())); + with_array.push(PrimitiveOrComponent::Integer(item)); } } else if let Some(with) = with_list.compounds() { for item in with { @@ -504,41 +493,39 @@ impl FormattedText { // for the /give system messages if let Some(b) = primitive.byte() { // interpreted as boolean - with_array.push(StringOrComponent::String( - if b != 0 { "true" } else { "false" }.to_string(), - )); + with_array.push(PrimitiveOrComponent::Boolean(b != 0)); } else if let Some(s) = primitive.short() { - with_array.push(StringOrComponent::String(s.to_string())); + with_array.push(PrimitiveOrComponent::Short(s)); } else if let Some(i) = primitive.int() { - with_array.push(StringOrComponent::String(i.to_string())); + with_array.push(PrimitiveOrComponent::Integer(i)); } else if let Some(l) = primitive.long() { - with_array.push(StringOrComponent::String(l.to_string())); + with_array.push(PrimitiveOrComponent::Long(l)); } else if let Some(f) = primitive.float() { - with_array.push(StringOrComponent::String(f.to_string())); + with_array.push(PrimitiveOrComponent::Float(f)); } else if let Some(d) = primitive.double() { - with_array.push(StringOrComponent::String(d.to_string())); + with_array.push(PrimitiveOrComponent::Double(d)); } else if let Some(s) = primitive.string() { - with_array.push(StringOrComponent::String(s.to_string())); + with_array.push(PrimitiveOrComponent::String(s.to_string())); } else { warn!( "couldn't parse {item:?} as FormattedText because it has a disallowed primitive" ); - with_array.push(StringOrComponent::String("?".to_string())); + with_array.push(PrimitiveOrComponent::String("?".to_string())); } } else if let Some(c) = FormattedText::from_nbt_compound(item) { if let FormattedText::Text(text_component) = c && text_component.base.siblings.is_empty() && text_component.base.style.is_empty() { - with_array.push(StringOrComponent::String(text_component.text)); + with_array.push(PrimitiveOrComponent::String(text_component.text)); continue; } - with_array.push(StringOrComponent::FormattedText( + with_array.push(PrimitiveOrComponent::FormattedText( FormattedText::from_nbt_compound(item)?, )); } else { warn!("couldn't parse {item:?} as FormattedText"); - with_array.push(StringOrComponent::String("?".to_string())); + with_array.push(PrimitiveOrComponent::String("?".to_string())); } } } else { @@ -698,6 +685,7 @@ mod tests { use serde_json::Value; use super::*; + use crate::style::TextColor; #[test] fn deserialize_translation() { @@ -710,8 +698,8 @@ mod tests { FormattedText::Translatable(TranslatableComponent::new( "translation.test.args".to_string(), vec![ - StringOrComponent::String("a".to_string()), - StringOrComponent::String("b".to_string()) + PrimitiveOrComponent::String("a".to_string()), + PrimitiveOrComponent::String("b".to_string()) ] )) ); @@ -733,7 +721,7 @@ mod tests { FormattedText::Translatable(TranslatableComponent::with_fallback( "translation.test.undefined".to_string(), Some("fallback: %s".to_string()), - vec![StringOrComponent::String("a".to_string())] + vec![PrimitiveOrComponent::String("a".to_string())] )) ); } @@ -746,4 +734,26 @@ mod tests { .unwrap(); assert!(FormattedText::deserialize(&j).is_err()); } + #[test] + fn deserialize_translation_primitive_args() { + let j: Value = serde_json::from_str( + r#"{"translate":"commands.list.players", "with": [1, 65536, "<players>", {"text": "unused", "color": "red"}]}"#, + ) + .unwrap(); + assert_eq!( + FormattedText::deserialize(&j).unwrap(), + FormattedText::Translatable(TranslatableComponent::new( + "commands.list.players".to_string(), + vec![ + PrimitiveOrComponent::Short(1), + PrimitiveOrComponent::Integer(65536), + PrimitiveOrComponent::String("<players>".to_string()), + PrimitiveOrComponent::FormattedText(FormattedText::Text( + TextComponent::new("unused") + .with_style(Style::new().color(Some(TextColor::parse("red").unwrap()))) + )) + ] + )) + ); + } } |
