use std::marker::PhantomData;
use yog_data::Schema;
pub struct ItemData<T> {
key: &'static str,
value: PhantomData<fn() -> T>,
}
impl<T: Schema + Default> ItemData<T> {
pub const fn new(key: &'static str) -> Self {
ItemData {
key,
value: PhantomData,
}
}
pub fn get(&self, player: &str, off_hand: bool) -> T {
crate::event::player::held_item_data(player, off_hand, self.stack_key())
.and_then(|r| yog_data::read_bytes(&r.bytes).ok())
.unwrap_or_default()
}
pub fn set(&self, player: &str, off_hand: bool, value: &T) -> bool {
crate::event::player::set_held_item_data(
player,
off_hand,
self.stack_key(),
yog_data::to_bytes(value),
)
}
pub fn update<R>(
&self,
player: &str,
off_hand: bool,
change: impl FnOnce(&mut T) -> R,
) -> Option<R> {
let mut value = self.get(player, off_hand);
let out = change(&mut value);
self.set(player, off_hand, &value).then_some(out)
}
fn stack_key(&self) -> String {
format!("{}{}{}", crate::mod_id(), yog_ids::sep::NAMESPACE, self.key)
}
}