firebase_rs_sdk/firestore/model/
document_key.rs

1use crate::firestore::error::{invalid_argument, FirestoreResult};
2use crate::firestore::model::ResourcePath;
3
4#[derive(Clone, Debug, PartialEq, Eq, Hash)]
5pub struct DocumentKey {
6    path: ResourcePath,
7}
8
9impl DocumentKey {
10    pub fn from_path(path: ResourcePath) -> FirestoreResult<Self> {
11        if path.len() < 2 || path.len() % 2 != 0 {
12            return Err(invalid_argument(
13                "Document keys must point to a document (even number of segments)",
14            ));
15        }
16        Ok(Self { path })
17    }
18
19    pub fn from_string(path: &str) -> FirestoreResult<Self> {
20        let resource = ResourcePath::from_string(path)?;
21        Self::from_path(resource)
22    }
23
24    pub fn collection_path(&self) -> ResourcePath {
25        self.path.without_last()
26    }
27
28    pub fn path(&self) -> &ResourcePath {
29        &self.path
30    }
31
32    pub fn id(&self) -> &str {
33        self.path
34            .last_segment()
35            .expect("DocumentKey path always has id")
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn validates_even_segments() {
45        let err = DocumentKey::from_string("cities").unwrap_err();
46        assert_eq!(err.code_str(), "firestore/invalid-argument");
47    }
48
49    #[test]
50    fn parses_valid_path() {
51        let key = DocumentKey::from_string("cities/sf").unwrap();
52        assert_eq!(key.id(), "sf");
53        assert_eq!(key.collection_path().canonical_string(), "cities");
54    }
55}