1use std::collections::BTreeMap;
2use std::fmt;
3
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use uuid::Uuid;
7
8#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
10#[serde(transparent)]
11pub struct WorkspaceId(Uuid);
12
13impl WorkspaceId {
14 pub fn new() -> Self {
16 Self(Uuid::now_v7())
17 }
18
19 pub fn parse(input: &str) -> Result<Self, uuid::Error> {
21 Uuid::parse_str(input).map(Self)
22 }
23}
24
25impl Default for WorkspaceId {
26 fn default() -> Self {
27 Self::new()
28 }
29}
30
31impl fmt::Display for WorkspaceId {
32 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
33 self.0.fmt(formatter)
34 }
35}
36
37#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
39#[serde(transparent)]
40pub struct NodeId(Uuid);
41
42impl NodeId {
43 pub fn new() -> Self {
45 Self(Uuid::now_v7())
46 }
47
48 pub fn parse(input: &str) -> Result<Self, uuid::Error> {
50 Uuid::parse_str(input).map(Self)
51 }
52}
53
54impl Default for NodeId {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60impl fmt::Display for NodeId {
61 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
62 self.0.fmt(formatter)
63 }
64}
65
66#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
68#[serde(transparent)]
69pub struct Revision(u64);
70
71impl Revision {
72 pub const INITIAL: Self = Self(1);
74
75 pub const fn new(value: u64) -> Option<Self> {
77 if value == 0 { None } else { Some(Self(value)) }
78 }
79
80 pub const fn next(self) -> Self {
86 match self.0.checked_add(1) {
87 Some(value) => Self(value),
88 None => panic!("revision overflow"),
89 }
90 }
91
92 pub const fn get(self) -> u64 {
94 self.0
95 }
96}
97
98#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
100#[serde(rename_all = "snake_case")]
101pub enum NodeKind {
102 Directory,
104 File,
106 Symlink,
108}
109
110#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
112pub struct Node {
113 pub workspace_id: WorkspaceId,
115 pub id: NodeId,
117 pub parent_id: Option<NodeId>,
119 pub name: String,
121 pub kind: NodeKind,
123 pub logical_size: u64,
125 pub created_at_ms: i64,
127 pub modified_at_ms: i64,
129 pub accessed_at_ms: i64,
131 pub revision: Revision,
133 pub attributes: BTreeMap<String, Value>,
135}