ousia_ledger/
value_object.rs1use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use uuid::Uuid;
5
6#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
7pub enum ValueObjectState {
8 Alive,
9 Reserved,
10 Burned,
11}
12
13impl ValueObjectState {
14 pub fn can_transition_to(&self, target: ValueObjectState) -> bool {
15 match (self, target) {
16 (s1, s2) if s1 == &s2 => true,
17 (ValueObjectState::Alive, ValueObjectState::Reserved) => true,
18 (ValueObjectState::Alive, ValueObjectState::Burned) => true,
19 (ValueObjectState::Reserved, ValueObjectState::Alive) => true,
20 (ValueObjectState::Reserved, ValueObjectState::Burned) => true,
21 (ValueObjectState::Burned, _) => false,
22 _ => false,
23 }
24 }
25
26 pub fn is_alive(&self) -> bool {
27 matches!(self, ValueObjectState::Alive)
28 }
29
30 pub fn is_reserved(&self) -> bool {
31 matches!(self, ValueObjectState::Reserved)
32 }
33
34 pub fn is_burned(&self) -> bool {
35 matches!(self, ValueObjectState::Burned)
36 }
37
38 pub fn is_spendable(&self) -> bool {
39 self.is_alive()
40 }
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct ValueObject {
45 pub id: Uuid,
46 pub asset: Uuid,
47 pub owner: Uuid,
48 pub amount: u64,
49 pub state: ValueObjectState,
50 pub reserved_for: Option<Uuid>,
51 pub created_at: DateTime<Utc>,
52}
53
54impl ValueObject {
55 pub fn new_alive(asset_id: Uuid, owner: Uuid, amount: u64) -> Self {
56 Self {
57 id: uuid::Uuid::now_v7(),
58 asset: asset_id,
59 owner,
60 amount,
61 state: ValueObjectState::Alive,
62 reserved_for: None,
63 created_at: Utc::now(),
64 }
65 }
66
67 pub fn new_reserved(asset_id: Uuid, owner: Uuid, amount: u64, reserved_for: Uuid) -> Self {
68 Self {
69 id: uuid::Uuid::now_v7(),
70 asset: asset_id,
71 owner,
72 amount,
73 state: ValueObjectState::Reserved,
74 reserved_for: Some(reserved_for),
75 created_at: Utc::now(),
76 }
77 }
78}