Skip to main content

syncweb_core/folder/
sync_mode.rs

1use std::{fmt, str::FromStr};
2
3use crate::error::{Result, SyncwebError};
4use serde::{Deserialize, Serialize};
5
6#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
7#[non_exhaustive]
8pub enum SyncMode {
9    #[default]
10    SendReceive,
11    SendOnly,
12    ReceiveOnly,
13}
14
15impl SyncMode {
16    #[must_use]
17    pub const fn can_write_locally(self) -> bool {
18        matches!(self, Self::SendReceive | Self::SendOnly)
19    }
20
21    #[must_use]
22    pub const fn can_grant_write(self) -> bool {
23        matches!(self, Self::SendReceive)
24    }
25
26    #[must_use]
27    pub const fn can_receive(self) -> bool {
28        !matches!(self, Self::SendOnly)
29    }
30}
31
32impl fmt::Display for SyncMode {
33    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
34        formatter.write_str(match self {
35            Self::SendReceive => "sendreceive",
36            Self::SendOnly => "sendonly",
37            Self::ReceiveOnly => "receiveonly",
38        })
39    }
40}
41
42impl FromStr for SyncMode {
43    type Err = SyncwebError;
44
45    fn from_str(value: &str) -> Result<Self> {
46        // Normalize: lowercase, replace hyphens and underscores with
47        // a single hyphen, strip leading/trailing separators.
48        let mut normalized = String::with_capacity(value.len());
49        let mut last_was_sep = true;
50        for ch in value.chars().flat_map(char::to_lowercase) {
51            if ch == '-' || ch == '_' {
52                if !last_was_sep {
53                    normalized.push('-');
54                    last_was_sep = true;
55                }
56            } else {
57                normalized.push(ch);
58                last_was_sep = false;
59            }
60        }
61        let trimmed = normalized.trim_end_matches('-');
62        match trimmed {
63            "send-receive" | "sendreceive" => Ok(Self::SendReceive),
64            "send-only" | "sendonly" => Ok(Self::SendOnly),
65            "receive-only" | "receiveonly" => Ok(Self::ReceiveOnly),
66            _ => Err(SyncwebError::InvalidSyncMode(value.to_owned())),
67        }
68    }
69}