Skip to main content

odp_core/
identity.rs

1use crate::{
2    ReferenceError, ResourceIdentity, ResourceType, derive_service_origin,
3    is_local_resource_identifier,
4};
5
6impl ResourceIdentity {
7    pub fn new(
8        service_document_url: &str,
9        resource_type: ResourceType,
10        id: impl Into<String>,
11    ) -> Result<Self, ReferenceError> {
12        let id = id.into();
13        if !is_local_resource_identifier(&id) {
14            return Err(ReferenceError::InvalidResourceIdentifier(
15                match resource_type {
16                    ResourceType::Collection => crate::Operation::GetCollection,
17                    ResourceType::Offering => crate::Operation::GetOffering,
18                },
19            ));
20        }
21        Ok(Self {
22            id,
23            service: derive_service_origin(service_document_url)?,
24            resource_type,
25        })
26    }
27
28    pub fn key(&self) -> String {
29        let resource_type = match self.resource_type {
30            ResourceType::Collection => "collection",
31            ResourceType::Offering => "offering",
32        };
33        format!("{}\0{}\0{}", self.service, resource_type, self.id)
34    }
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40
41    #[test]
42    fn composes_global_resource_identity() {
43        let identity = ResourceIdentity::new(
44            "https://shop.example/.well-known/odp",
45            ResourceType::Offering,
46            "plant-1",
47        )
48        .unwrap();
49        assert_eq!(identity.service, "https://shop.example");
50        assert_eq!(identity.key(), "https://shop.example\0offering\0plant-1");
51    }
52}