coven_format/
coordinates.rs1use crate::{error::Rule, file_reference::FileReference, Error};
5use coven_crypto::SecretText;
6use coven_foundation::id_source::DeviceId;
7
8#[derive(Debug)]
10pub enum Coordinates {
11 Cloud(FileReference),
13 DeviceOnly(DeviceId),
15}
16
17impl Coordinates {
18 #[expect(clippy::map_err_ignore, reason = "malformed coordinates are invalid as a whole")]
21 pub fn decode(text: &str) -> Result<Self, Error> {
22 if let Some(device) = text.strip_prefix("device ") {
23 let number = crate::path::canonical_decimal(device).ok_or_else(invalid)?;
24 return Ok(Self::DeviceOnly(DeviceId(number)));
25 }
26 FileReference::decode(text).map(Self::Cloud).map_err(|_| invalid())
27 }
28
29 pub fn encode(&self) -> SecretText {
31 match self {
32 Self::Cloud(reference) => reference.encode(),
33 Self::DeviceOnly(device) => SecretText::new(format!("device {}", device.0)),
34 }
35 }
36}
37
38fn invalid() -> Error {
39 Error::Invalid { field: "file coordinates", rule: Rule::KeyEncoding }
40}
41
42#[cfg(test)]
43#[path = "coordinates_tests.rs"]
44mod tests;