diff --git a/crates/client/option/src/enums/attack_indicator.rs b/crates/client/option/src/enums/attack_indicator.rs index 8a7da12b..f102ecde 100644 --- a/crates/client/option/src/enums/attack_indicator.rs +++ b/crates/client/option/src/enums/attack_indicator.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, fmt::Display}; use enum_iterator::Sequence; -use rimecraft_text::{format_localization_key, Localizable}; +use rimecraft_text::{format_localization_key, Localize}; use super::ByUSizeId; @@ -38,7 +38,7 @@ impl Display for AttackIndicator { } } -impl Localizable for AttackIndicator { +impl Localize for AttackIndicator { fn localization_key(&self) -> Cow<'_, str> { Cow::Owned(format_localization_key!( "options", diff --git a/crates/client/option/src/enums/graphics_mode.rs b/crates/client/option/src/enums/graphics_mode.rs index 3b18ead4..93620bd0 100644 --- a/crates/client/option/src/enums/graphics_mode.rs +++ b/crates/client/option/src/enums/graphics_mode.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, fmt::Display}; use enum_iterator::Sequence; -use rimecraft_text::{format_localization_key, Localizable}; +use rimecraft_text::{format_localization_key, Localize}; use super::ByUSizeId; @@ -38,7 +38,7 @@ impl Display for GraphicsMode { } } -impl Localizable for GraphicsMode { +impl Localize for GraphicsMode { fn localization_key(&self) -> Cow<'_, str> { Cow::Owned(format_localization_key!( "options", diff --git a/crates/client/option/src/enums/narrator_mode.rs b/crates/client/option/src/enums/narrator_mode.rs index 3d0cf593..792241c5 100644 --- a/crates/client/option/src/enums/narrator_mode.rs +++ b/crates/client/option/src/enums/narrator_mode.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, fmt::Display}; use enum_iterator::Sequence; -use rimecraft_text::{format_localization_key, Localizable}; +use rimecraft_text::{format_localization_key, Localize}; use super::ByUSizeId; @@ -57,7 +57,7 @@ impl NarratorMode { } } -impl Localizable for NarratorMode { +impl Localize for NarratorMode { fn localization_key(&self) -> Cow<'_, str> { Cow::Owned(format_localization_key!( "options", diff --git a/crates/client/option/src/enums/particles_mode.rs b/crates/client/option/src/enums/particles_mode.rs index ca0f66e1..2cd53fa8 100644 --- a/crates/client/option/src/enums/particles_mode.rs +++ b/crates/client/option/src/enums/particles_mode.rs @@ -3,7 +3,7 @@ use std::{borrow::Cow, fmt::Display}; use enum_iterator::Sequence; -use rimecraft_text::{format_localization_key, Localizable}; +use rimecraft_text::{format_localization_key, Localize}; use super::ByUSizeId; @@ -39,7 +39,7 @@ impl Display for ParticlesMode { } } -impl Localizable for ParticlesMode { +impl Localize for ParticlesMode { fn localization_key(&self) -> Cow<'_, str> { Cow::Owned(format_localization_key!( "options", diff --git a/crates/core/component/src/lib.rs b/crates/core/component/src/lib.rs index 684d00d4..b0863ef6 100644 --- a/crates/core/component/src/lib.rs +++ b/crates/core/component/src/lib.rs @@ -5,7 +5,7 @@ use std::{any::TypeId, cell::UnsafeCell, fmt::Debug, hash::Hash, marker::Phantom use bytes::{Buf, BufMut}; use edcode2::{Decode, Encode}; use rimecraft_global_cx::{ - nbt_edcode::{ReadNbt, UpdateNbt, WriteNbt}, + nbt::{ReadNbt, UpdateNbt, WriteNbt}, ProvideIdTy, }; use rimecraft_registry::{ProvideRegistry, Reg}; diff --git a/crates/core/global-cx/Cargo.toml b/crates/core/global-cx/Cargo.toml index 0a96a417..809a967c 100644 --- a/crates/core/global-cx/Cargo.toml +++ b/crates/core/global-cx/Cargo.toml @@ -13,12 +13,14 @@ maintenance = { status = "passively-maintained" } [dependencies] serde = { version = "1.0", default-features = false, optional = true } +edcode2 = { path = "../../util/edcode2", package = "rimecraft-edcode2", optional = true } [features] default = ["std"] std = [] serde = ["dep:serde"] nbt = ["serde"] +edcode = ["dep:edcode2", "std"] [lints] workspace = true diff --git a/crates/core/global-cx/src/edcode.rs b/crates/core/global-cx/src/edcode.rs new file mode 100644 index 00000000..b3aff9ce --- /dev/null +++ b/crates/core/global-cx/src/edcode.rs @@ -0,0 +1,56 @@ +//! `edcode2` crate integration. + +use core::marker::PhantomData; + +use edcode2::{Buf, BufMut, Decode, Encode}; + +use crate::nbt::{ReadNbt, WriteNbt}; + +/// A type that wraps a value with a context. +#[derive(Debug)] +pub struct Nbt(pub T, PhantomData); + +impl Nbt { + /// Creates a new `Nbt` with the given value. + #[inline] + pub const fn new(value: T) -> Self { + Self(value, PhantomData) + } + + /// Consumes the `Nbt` and returns the inner value. + #[inline] + pub fn into_inner(self) -> T { + self.0 + } +} + +impl From for Nbt { + #[inline] + fn from(value: T) -> Self { + Self::new(value) + } +} + +impl Encode for Nbt +where + B: BufMut, + Cx: for<'s> WriteNbt<&'s T>, +{ + #[inline] + fn encode(&self, buf: B) -> Result<(), edcode2::BoxedError<'static>> { + Cx::write_nbt(&self.0, buf.writer()).map_err(Into::into) + } +} + +impl<'de, B, T, Cx> Decode<'de, B> for Nbt +where + B: Buf, + Cx: ReadNbt, +{ + #[inline] + fn decode(buf: B) -> Result> { + Cx::read_nbt(buf.reader()) + .map(Self::new) + .map_err(Into::into) + } +} diff --git a/crates/core/global-cx/src/lib.rs b/crates/core/global-cx/src/lib.rs index ae50027c..8141d07d 100644 --- a/crates/core/global-cx/src/lib.rs +++ b/crates/core/global-cx/src/lib.rs @@ -15,6 +15,15 @@ extern crate std; use core::{fmt::Display, hash::Hash}; +#[cfg(feature = "std")] +pub mod nbt; + +#[deprecated = "use `nbt` feature instead"] +pub use nbt as nbt_edcode; + +#[cfg(feature = "edcode")] +pub mod edcode; + /// Marker trait for global contexts. /// /// # Safety @@ -51,61 +60,3 @@ pub trait ProvideNbtTy: GlobalContext { /// Function that converts a `Compound` to a `Deserializer`. fn compound_to_deserializer(compound: &Self::Compound) -> impl serde::Deserializer<'_>; } - -/// NBT `edcode`-ing related marker traits. -#[cfg(feature = "std")] -pub mod nbt_edcode { - use std::io; - - use crate::GlobalContext; - - /// Marker trait for global contexts that can write nbt tags to a [`io::Write`] object. - pub trait WriteNbt: GlobalContext { - /// Function that performs writing operation. - /// - /// # Errors - /// - /// I/O errors. - fn write_nbt(value: T, writer: W) -> Result<(), io::Error> - where - W: io::Write; - } - - /// Marker trait for global contexts that can read nbt tags from a [`io::Read`] object. - pub trait ReadNbt: GlobalContext { - /// Function that performs reading operation. - /// - /// # Errors - /// - /// I/O errors. - fn read_nbt(reader: R) -> Result - where - R: io::Read; - } - - /// Marker trait for global contexts that can update existing nbt tags from a [`io::Read`] object. - pub trait UpdateNbt: GlobalContext { - /// Function that performs updating operation. - /// - /// # Errors - /// - /// I/O errors. - fn update_nbt(value: &mut T, reader: R) -> Result<(), io::Error> - where - R: io::Read; - } - - impl UpdateNbt for Cx - where - Cx: ReadNbt, - { - #[inline] - fn update_nbt(value: &mut T, reader: R) -> Result<(), io::Error> - where - R: io::Read, - { - *value = Self::read_nbt(reader)?; - Ok(()) - } - } -} diff --git a/crates/core/global-cx/src/nbt.rs b/crates/core/global-cx/src/nbt.rs new file mode 100644 index 00000000..2ec83c59 --- /dev/null +++ b/crates/core/global-cx/src/nbt.rs @@ -0,0 +1,55 @@ +//! NBT `edcode`-ing related marker traits. + +use std::io; + +use crate::GlobalContext; + +/// Marker trait for global contexts that can write nbt tags to a [`io::Write`] object. +pub trait WriteNbt: GlobalContext { + /// Function that performs writing operation. + /// + /// # Errors + /// + /// I/O errors. + fn write_nbt(value: T, writer: W) -> Result<(), io::Error> + where + W: io::Write; +} + +/// Marker trait for global contexts that can read nbt tags from a [`io::Read`] object. +pub trait ReadNbt: GlobalContext { + /// Function that performs reading operation. + /// + /// # Errors + /// + /// I/O errors. + fn read_nbt(reader: R) -> Result + where + R: io::Read; +} + +/// Marker trait for global contexts that can update existing nbt tags from a [`io::Read`] object. +pub trait UpdateNbt: GlobalContext { + /// Function that performs updating operation. + /// + /// # Errors + /// + /// I/O errors. + fn update_nbt(value: &mut T, reader: R) -> Result<(), io::Error> + where + R: io::Read; +} + +impl UpdateNbt for Cx +where + Cx: ReadNbt, +{ + #[inline] + fn update_nbt(value: &mut T, reader: R) -> Result<(), io::Error> + where + R: io::Read, + { + *value = Self::read_nbt(reader)?; + Ok(()) + } +} diff --git a/crates/core/text/Cargo.toml b/crates/core/text/Cargo.toml index 9aeb0fce..e9bb3e7f 100644 --- a/crates/core/text/Cargo.toml +++ b/crates/core/text/Cargo.toml @@ -16,13 +16,13 @@ rimecraft-global-cx = { path = "../global-cx" } rgb = "0.8" rimecraft-fmt = { path = "../../util/fmt" } serde = { version = "1.0", features = ["derive"], optional = true } -rimecraft-edcode2 = { path = "../../util/edcode2", optional = true } +edcode2 = { path = "../../util/edcode2", optional = true, package = "rimecraft-edcode2" } [features] default = ["macros"] serde = ["dep:serde"] macros = [] -edcode = ["dep:rimecraft-edcode2"] +edcode = ["dep:edcode2", "serde", "rimecraft-global-cx/edcode"] [lints] workspace = true diff --git a/crates/core/text/src/lib.rs b/crates/core/text/src/lib.rs index 599718ec..d1fd1efd 100644 --- a/crates/core/text/src/lib.rs +++ b/crates/core/text/src/lib.rs @@ -182,10 +182,11 @@ where /// Global context for text. /// -/// The associated types [`Texts::T`] and [`Texts::StyleExt`] should be applied to [`Text`] when used. +/// The associated type `Content` and `StyleExt` should be applied to [`Text`] when used. pub trait ProvideTextTy: GlobalContext { /// Generic `T` that should be applied to [`Text`]. - type Content; + type Content: Plain; + /// Generic `StyleExt` that should be applied to [`Text`]. type StyleExt; } @@ -194,11 +195,15 @@ pub trait ProvideTextTy: GlobalContext { pub type Text = RawText<::Content, ::StyleExt>; /// A localizable value. -pub trait Localizable { +pub trait Localize { /// Returns the localization key of this value. fn localization_key(&self) -> Cow<'_, str>; } +/// A seed for encoding and decoding [`Text`] through `edcode2` crate. +#[cfg(feature = "edcode")] +pub type EdcodeSeed = rimecraft_global_cx::edcode::Nbt, Cx>; + #[cfg(test)] mod tests;