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