Files
guardian/crates/guardian_core/src/srs/voice.rs
2023-12-22 04:50:17 +01:00

81 lines
2.0 KiB
Rust

use std::{
borrow::Cow,
hash::{Hash, Hasher},
};
use bevy::{
ecs::{component::Component, reflect::ReflectComponent},
reflect::{std_traits::ReflectDefault, Reflect},
utils::AHasher,
};
#[derive(Reflect, Component, Clone)]
#[reflect(Component, Default, Debug)]
pub struct VoiceMessage {
hash: u64,
message: Cow<'static, str>,
}
impl Default for VoiceMessage {
fn default() -> Self {
VoiceMessage::new("")
}
}
#[allow(unused)]
impl VoiceMessage {
/// Creates a new [`VoiceMessage`] from any string-like type.
///
/// The internal hash will be computed immediately.
pub fn new(message: impl Into<Cow<'static, str>>) -> Self {
let message = message.into();
let mut message = VoiceMessage { message, hash: 0 };
message.update_hash();
message
}
/// Sets the entity's message.
///
/// The internal hash will be re-computed.
#[inline(always)]
pub fn set(&mut self, message: impl Into<Cow<'static, str>>) {
*self = VoiceMessage::new(message);
}
/// Updates the message of the entity in place.
///
/// This will allocate a new string if the message was previously
/// created from a borrow.
#[inline(always)]
pub fn mutate<F: FnOnce(&mut String)>(&mut self, f: F) {
f(self.message.to_mut());
self.update_hash();
}
/// Gets the message of the entity as a `&str`.
#[inline(always)]
pub fn as_str(&self) -> &str {
&self.message
}
fn update_hash(&mut self) {
let mut hasher = AHasher::default();
self.message.hash(&mut hasher);
self.hash = hasher.finish();
}
}
impl std::fmt::Display for VoiceMessage {
#[inline(always)]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&self.message, f)
}
}
impl std::fmt::Debug for VoiceMessage {
#[inline(always)]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Debug::fmt(&self.message, f)
}
}