firebase_rs_sdk/firestore/model/
document_key.rs1use 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}