aboutsummaryrefslogtreecommitdiff
path: root/minecraft-chat/src/component.rs
diff options
context:
space:
mode:
authormat <github@matdoes.dev>2021-12-15 23:10:55 -0600
committermat <github@matdoes.dev>2021-12-15 23:10:55 -0600
commit9642558f8f8d983a7087f15d68be8cf07a85f0c2 (patch)
tree5f0a967f005cd5db510a13ab290c8ad6669b25aa /minecraft-chat/src/component.rs
parent72aefe871ca4983431b1a0b707b472e73ffea836 (diff)
downloadazalea-drasl-9642558f8f8d983a7087f15d68be8cf07a85f0c2.tar.xz
azalea
Diffstat (limited to 'minecraft-chat/src/component.rs')
-rw-r--r--minecraft-chat/src/component.rs262
1 files changed, 0 insertions, 262 deletions
diff --git a/minecraft-chat/src/component.rs b/minecraft-chat/src/component.rs
deleted file mode 100644
index 1ed1f836..00000000
--- a/minecraft-chat/src/component.rs
+++ /dev/null
@@ -1,262 +0,0 @@
-use serde::{de, Deserialize, Deserializer};
-
-use crate::{
- base_component::BaseComponent,
- style::{ChatFormatting, Style},
- text_component::TextComponent,
- translatable_component::{StringOrComponent, TranslatableComponent},
-};
-
-#[derive(Clone, Debug)]
-pub enum Component {
- Text(TextComponent),
- Translatable(TranslatableComponent),
-}
-
-lazy_static! {
- pub static ref DEFAULT_STYLE: Style = Style {
- color: Some(ChatFormatting::WHITE.try_into().unwrap()),
- ..Style::default()
- };
-}
-
-/// A chat component
-impl Component {
- // TODO: is it possible to use a macro so this doesn't have to be duplicated?
-
- pub fn get_base_mut(&mut self) -> &mut BaseComponent {
- match self {
- Self::Text(c) => &mut c.base,
- Self::Translatable(c) => &mut c.base,
- }
- }
-
- pub fn get_base(&self) -> &BaseComponent {
- match self {
- Self::Text(c) => &c.base,
- Self::Translatable(c) => &c.base,
- }
- }
-
- /// Add a component as a sibling of this one
- fn append(&mut self, sibling: Component) {
- self.get_base_mut().siblings.push(sibling);
- }
-
- /// Get the "separator" component from the json
- fn parse_separator(json: &serde_json::Value) -> Result<Option<Component>, serde_json::Error> {
- if json.get("separator").is_some() {
- return Ok(Some(Component::deserialize(
- json.get("separator").unwrap(),
- )?));
- }
- Ok(None)
- }
-
- /// Convert this component into an ansi string
- pub fn to_ansi(&self, default_style: Option<&Style>) -> String {
- // default the default_style to white if it's not set
- let default_style: &Style = default_style.unwrap_or(&DEFAULT_STYLE);
-
- // this contains the final string will all the ansi escape codes
- let mut built_string = String::new();
- // this style will update as we visit components
- let mut running_style = Style::default();
-
- for component in self.clone().into_iter() {
- let component_text = match &component {
- Self::Text(c) => &c.text,
- Self::Translatable(c) => &c.key,
- };
- let component_style = &component.get_base().style;
-
- let ansi_text = running_style.compare_ansi(component_style, default_style);
- built_string.push_str(&ansi_text);
- built_string.push_str(component_text);
-
- running_style.apply(component_style);
- }
-
- if !running_style.is_empty() {
- built_string.push_str("\u{1b}[m");
- }
-
- built_string
- }
-}
-
-impl IntoIterator for Component {
- /// Recursively call the function for every component in this component
- fn into_iter(self) -> Self::IntoIter {
- let base = self.get_base();
- let siblings = base.siblings.clone();
- let mut v: Vec<Component> = Vec::with_capacity(siblings.len() + 1);
- v.push(self);
- for sibling in siblings {
- v.extend(sibling.into_iter());
- }
-
- v.into_iter()
- }
-
- type Item = Component;
- type IntoIter = std::vec::IntoIter<Self::Item>;
-}
-
-impl<'de> Deserialize<'de> for Component {
- fn deserialize<D>(de: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- let json: serde_json::Value = serde::Deserialize::deserialize(de)?;
-
- // we create a component that we might add siblings to
- let mut component: Component;
-
- // if it's primitive, make it a text component
- if !json.is_array() && !json.is_object() {
- return Ok(Component::Text(TextComponent::new(
- json.as_str().unwrap_or("").to_string(),
- )));
- }
- // if it's an object, do things with { text } and stuff
- else if json.is_object() {
- if json.get("text").is_some() {
- let text = json.get("text").unwrap().as_str().unwrap_or("").to_string();
- component = Component::Text(TextComponent::new(text));
- } else if json.get("translate").is_some() {
- let translate = json.get("translate").unwrap().to_string();
- if json.get("with").is_some() {
- let with = json.get("with").unwrap().as_array().unwrap();
- 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 = Component::deserialize(item).map_err(de::Error::custom)?;
- if let Component::Text(text_component) = c {
- if text_component.base.siblings.is_empty()
- && text_component.base.style.is_empty()
- {
- with_array.push(StringOrComponent::String(text_component.text));
- break;
- }
- }
- with_array.push(StringOrComponent::Component(
- Component::deserialize(item).map_err(de::Error::custom)?,
- ));
- }
- component =
- Component::Translatable(TranslatableComponent::new(translate, with_array));
- } else {
- // if it doesn't have a "with", just have the with_array be empty
- component =
- Component::Translatable(TranslatableComponent::new(translate, Vec::new()));
- }
- } else if json.get("score").is_some() {
- // object = GsonHelper.getAsJsonObject(jsonObject, "score");
- let score_json = json.get("score").unwrap();
- // if (!object.has("name") || !object.has("objective")) throw new JsonParseException("A score component needs a least a name and an objective");
- // ScoreComponent scoreComponent = new ScoreComponent(GsonHelper.getAsString((JsonObject)object, "name"), GsonHelper.getAsString((JsonObject)object, "objective"));
- if score_json.get("name").is_none() || score_json.get("objective").is_none() {
- return Err(de::Error::missing_field(
- "A score component needs at least a name and an objective",
- ));
- }
- // TODO
- return Err(de::Error::custom(
- "score text components aren't yet supported",
- ));
- // component = ScoreComponent
- } else if json.get("selector").is_some() {
- // } else if (jsonObject.has("selector")) {
- // object = this.parseSeparator(type, jsonDeserializationContext, jsonObject);
- // SelectorComponent selectorComponent = new SelectorComponent(GsonHelper.getAsString(jsonObject, "selector"), (Optional<Component>)object);
-
- return Err(de::Error::custom(
- "selector text components aren't yet supported",
- ));
- // } else if (jsonObject.has("keybind")) {
- // KeybindComponent keybindComponent = new KeybindComponent(GsonHelper.getAsString(jsonObject, "keybind"));
- } else if json.get("keybind").is_some() {
- return Err(de::Error::custom(
- "keybind text components aren't yet supported",
- ));
- } else {
- // } else {
- // if (!jsonObject.has("nbt")) throw new JsonParseException("Don't know how to turn " + jsonElement + " into a Component");
- if json.get("nbt").is_none() {
- return Err(de::Error::custom(
- format!("Don't know how to turn {} into a Component", json).as_str(),
- ));
- }
- // object = GsonHelper.getAsString(jsonObject, "nbt");
- let _nbt = json.get("nbt").unwrap().to_string();
- // Optional<Component> optional = this.parseSeparator(type, jsonDeserializationContext, jsonObject);
- let _separator = Component::parse_separator(&json).map_err(de::Error::custom)?;
-
- let _interpret = match json.get("interpret") {
- Some(v) => v.as_bool().ok_or(Some(false)).unwrap(),
- None => false,
- };
- // boolean bl = GsonHelper.getAsBoolean(jsonObject, "interpret", false);
- // if (jsonObject.has("block")) {
- if json.get("block").is_some() {}
- return Err(de::Error::custom(
- "nbt text components aren't yet supported",
- ));
- // NbtComponent.BlockNbtComponent blockNbtComponent = new NbtComponent.BlockNbtComponent((String)object, bl, GsonHelper.getAsString(jsonObject, "block"), optional);
- // } else if (jsonObject.has("entity")) {
- // NbtComponent.EntityNbtComponent entityNbtComponent = new NbtComponent.EntityNbtComponent((String)object, bl, GsonHelper.getAsString(jsonObject, "entity"), optional);
- // } else {
- // if (!jsonObject.has("storage")) throw new JsonParseException("Don't know how to turn " + jsonElement + " into a Component");
- // NbtComponent.StorageNbtComponent storageNbtComponent = new NbtComponent.StorageNbtComponent((String)object, bl, new ResourceLocation(GsonHelper.getAsString(jsonObject, "storage")), optional);
- // }
- // }
- }
- // if (jsonObject.has("extra")) {
- // object = GsonHelper.getAsJsonArray(jsonObject, "extra");
- // if (object.size() <= 0) throw new JsonParseException("Unexpected empty array of components");
- // for (int i = 0; i < object.size(); ++i) {
- // var5_17.append(this.deserialize(object.get(i), type, jsonDeserializationContext));
- // }
- // }
- // var5_17.setStyle((Style)jsonDeserializationContext.deserialize(jsonElement, Style.class));
- // return var5_17;
- // }
- if json.get("extra").is_some() {
- let extra = match json.get("extra").unwrap().as_array() {
- Some(r) => r,
- None => return Err(de::Error::custom("Extra isn't an array")),
- };
- if extra.is_empty() {
- return Err(de::Error::custom("Unexpected empty array of components"));
- }
- for extra_component in extra {
- let sibling =
- Component::deserialize(extra_component).map_err(de::Error::custom)?;
- component.append(sibling);
- }
- }
-
- let style = Style::deserialize(&json);
- component.get_base_mut().style = style;
-
- return Ok(component);
- }
- // ok so it's not an object, if it's an array deserialize every item
- else if !json.is_array() {
- return Err(de::Error::custom(
- format!("Don't know how to turn {} into a Component", json).as_str(),
- ));
- }
- let json_array = json.as_array().unwrap();
- // the first item in the array is the one that we're gonna return, the others are siblings
- let mut component = Component::deserialize(&json_array[0]).map_err(de::Error::custom)?;
- for i in 1..json_array.len() {
- component.append(
- Component::deserialize(json_array.get(i).unwrap()).map_err(de::Error::custom)?,
- );
- }
- Ok(component)
- }
-}