1use std::{marker::PhantomData, mem};
6
7use derive_where::derive_where;
8use spru::common::error::AnyResult;
9use tagset::tagset;
10use telety::telety;
11
12#[telety(crate::cloned)]
13#[tagset(Create<T>)]
14#[tagset(Update<T>)]
15#[tagset(Destroy<T>)]
16#[tagset(reserved(..8))]
17pub struct Actions<T>;
18
19pub fn create<T>(value: T) -> Create<T> {
20 Create { value }
21}
22
23pub fn default<T: Default>() -> Create<T> {
24 create(T::default())
25}
26
27pub fn update<T>(value: T) -> Update<T> {
28 Update { value }
29}
30
31pub fn update_default<T: Default>() -> Update<T> {
32 update(T::default())
33}
34
35pub fn destroy<T>() -> Destroy<T> {
36 Destroy(PhantomData)
37}
38
39#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, spru::action::Create)]
40#[must_use]
41pub struct Create<T> {
42 value: T,
43}
44
45impl<T> spru::action::Create for Create<T>
46where
47 T: Clone,
48{
49 type T = T;
50 type Undo = Destroy<T>;
51
52 fn create(&self) -> AnyResult<(Self::T, Self::Undo)> {
53 Ok((self.value.clone(), Destroy(PhantomData)))
54 }
55}
56
57#[derive_where(Debug, Clone, Serialize, Deserialize)]
58#[derive(spru::action::Destroy)]
59#[must_use]
60pub struct Destroy<T>(PhantomData<fn() -> T>);
61
62impl<T> spru::action::Destroy for Destroy<T> {
63 type T = T;
64 type Undo = Create<T>;
65
66 fn destroy(&self, value: Self::T) -> AnyResult<Self::Undo> {
67 Ok(Create { value })
68 }
69}
70
71#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize, spru::action::Update)]
72#[must_use]
73pub struct Update<T> {
74 value: T,
75}
76
77impl<T: Clone> spru::action::Update for Update<T> {
78 type T = T;
79 type Undo = Self;
80
81 #[allow(refining_impl_trait)]
82 fn update(&self, value: &mut Self::T) -> AnyResult<Self::Undo> {
83 let old = mem::replace(&mut *value, self.value.clone());
84 Ok(Self { value: old })
85 }
86}