Skip to main content

harmos_domain/model/storage/
directory.rs

1/* ***
2 *
3 * Harmos
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * ***
8 */
9
10// Shared Directory Discovery Contract
11
12/* === Modules === */
13
14/* === Re-Exports === */
15
16/* === Imports === */
17
18// Standard Library Imports
19use std::path::PathBuf;
20// Third Party Imports
21// Local Imports
22use super::codec::{Flag, Nested, Repeated, Text, Unsigned, product, variants};
23use super::files::codec::LocalPath;
24use crate::MemorySize;
25
26/* === Constants === */
27
28/* === Macros === */
29
30product!(DirectoryRule { pattern: Text => 1, include: Flag => 2 });
31product!(DirectorySelection { root: LocalPath => 1, recursive: Flag => 2, rules: Repeated<DirectoryRule> => 3 });
32product!(DirectoryEntry { path: Text => 1, directory: Flag => 2, length: Unsigned => 3 });
33product!(DirectoryCompletion { entries: Unsigned => 1 });
34variants!(DirectoryEvent {
35    0, 1, "existing": Self::Existing(entry) => { entry: Nested<DirectoryEntry> => 1 } => Self::Existing(entry);
36    1, 2, "initial_scan_complete": Self::InitialScanComplete => {} => Self::InitialScanComplete;
37    2, 3, "created": Self::Created(entry) => { entry: Nested<DirectoryEntry> => 1 } => Self::Created(entry);
38    3, 4, "modified": Self::Modified(entry) => { entry: Nested<DirectoryEntry> => 1 } => Self::Modified(entry);
39    4, 5, "removed": Self::Removed { path } => { path: Text => 1 } => Self::Removed { path };
40    5, 6, "renamed": Self::Renamed { from, to } => { from: Text => 1, to: Text => 2 } => Self::Renamed { from, to };
41    6, 7, "rescan_required": Self::RescanRequired => {} => Self::RescanRequired;
42});
43
44/* === Type Aliases === */
45
46/* === Structs === */
47
48#[derive(Clone, Debug, PartialEq, Eq)]
49pub struct DirectoryRule {
50    pub pattern: String,
51    pub include: bool,
52}
53
54#[derive(Clone, Debug, PartialEq, Eq)]
55pub struct DirectorySelection {
56    pub root: PathBuf,
57    pub recursive: bool,
58    pub rules: Vec<DirectoryRule>,
59}
60
61#[derive(Clone, Debug, PartialEq, Eq)]
62pub struct DirectoryEntry {
63    pub path: String,
64    pub directory: bool,
65    pub length: u64,
66}
67
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub struct DirectoryCompletion {
70    pub entries: u64,
71}
72
73/* === Enums === */
74
75#[derive(Clone, Debug, PartialEq, Eq)]
76pub enum DirectoryEvent {
77    Existing(DirectoryEntry),
78    InitialScanComplete,
79    Created(DirectoryEntry),
80    Modified(DirectoryEntry),
81    Removed { path: String },
82    Renamed { from: String, to: String },
83    RescanRequired,
84}
85
86/* === Traits === */
87
88/* === Implementations === */
89
90impl MemorySize for DirectoryRule {
91    fn memory_size(&self) -> usize {
92        std::mem::size_of::<Self>().saturating_add(self.pattern.capacity())
93    }
94}
95impl MemorySize for DirectorySelection {
96    fn memory_size(&self) -> usize {
97        std::mem::size_of::<Self>()
98            .saturating_add(self.root.capacity())
99            .saturating_add(self.rules.memory_size().saturating_sub(std::mem::size_of_val(&self.rules)))
100    }
101}
102impl MemorySize for DirectoryEntry {
103    fn memory_size(&self) -> usize {
104        std::mem::size_of::<Self>().saturating_add(self.path.capacity())
105    }
106}
107impl MemorySize for DirectoryCompletion {
108    fn memory_size(&self) -> usize {
109        std::mem::size_of::<Self>()
110    }
111}
112impl MemorySize for DirectoryEvent {
113    fn memory_size(&self) -> usize {
114        let extra = match self {
115            Self::Existing(entry) | Self::Created(entry) | Self::Modified(entry) => entry.path.capacity(),
116            Self::Removed { path } => path.capacity(),
117            Self::Renamed { from, to } => from.capacity().saturating_add(to.capacity()),
118            Self::InitialScanComplete | Self::RescanRequired => 0,
119        };
120        std::mem::size_of::<Self>().saturating_add(extra)
121    }
122}
123
124/* === Public Functions === */
125
126/* === Private Functions === */
127
128/* === Tests === */