spanner_rs/
resource.rs

1/// A trait for identifiable resources within Cloud Spanner.
2///
3/// The format is typically something like `<kind>/<name>` where `kind` is the plural form
4/// of the resource kind, e.g.: `projects` or `databases` and `name` is the name of a particular instance of that resource.
5///
6/// For example, the database resource named `my-database` in the `my-instance` instance in the `my-gcp-project` project
7/// will have the following identifier: `projects/my-gcp-project/instances/my-instance/databases/my-database`.
8pub trait SpannerResource {
9    /// The name of this particular instance of the resource.
10    fn name(&self) -> &str;
11
12    /// The full path to all resources under the same parent.
13    ///
14    /// For example, for the `InstanceId` resource, this would return something like `projects/my-project/instances`
15    fn resources_path(&self) -> String;
16
17    /// The full path to this particular resource.
18    ///
19    /// For example, `projects/my-project/instances/my-instance`
20    fn id(&self) -> String {
21        format!("{}/{}", self.resources_path(), self.name())
22    }
23}
24
25/// The resource that identifies a particular GCP project.
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct ProjectId(String);
28
29impl ProjectId {
30    /// Creates a new `ProjectId` resource using the specified name.
31    pub fn new(name: &str) -> Self {
32        Self(name.to_string())
33    }
34}
35
36impl SpannerResource for ProjectId {
37    fn name(&self) -> &str {
38        &self.0
39    }
40
41    fn resources_path(&self) -> String {
42        "projects".to_string()
43    }
44}
45
46/// The resource that identifies a Cloud Spanner instance in a particular GCP project.
47#[derive(Debug, Clone, PartialEq, Eq)]
48pub struct InstanceId(ProjectId, String);
49
50impl InstanceId {
51    /// Creates a new `InstanceId` resource using the specified project resource and name.
52    pub fn new(project: ProjectId, name: &str) -> Self {
53        Self(project, name.to_string())
54    }
55
56    /// Returns a reference to the project hosting this Cloud Spanner instance.
57    pub fn project(&self) -> &ProjectId {
58        &self.0
59    }
60}
61
62impl SpannerResource for InstanceId {
63    fn name(&self) -> &str {
64        &self.1
65    }
66
67    fn resources_path(&self) -> String {
68        format!("{}/instances", self.0.id())
69    }
70}
71
72/// The resource that identifies a Cloud Spanner database in a particular Cloud Spanner instance.
73#[derive(Debug, Clone, PartialEq, Eq)]
74pub struct DatabaseId(InstanceId, String);
75impl DatabaseId {
76    /// Creates a new `DatabaseId` resource using the specified instance resource and name.
77    pub fn new(instance: InstanceId, name: &str) -> Self {
78        Self(instance, name.to_string())
79    }
80}
81
82impl SpannerResource for DatabaseId {
83    fn name(&self) -> &str {
84        &self.1
85    }
86
87    fn resources_path(&self) -> String {
88        format!("{}/databases", self.0.id())
89    }
90}
91
92#[cfg(test)]
93mod test {
94    use super::*;
95
96    #[test]
97    fn test_project_id() {
98        let project_id = ProjectId::new("test-project");
99        assert_eq!(project_id.name(), "test-project");
100        assert_eq!(project_id.resources_path(), "projects".to_string());
101        assert_eq!(project_id.id(), "projects/test-project".to_string());
102    }
103    #[test]
104    fn test_instance_id() {
105        let instance_id = InstanceId::new(ProjectId::new("test-project"), "test-instance");
106        assert_eq!(instance_id.name(), "test-instance");
107        assert_eq!(
108            instance_id.resources_path(),
109            "projects/test-project/instances"
110        );
111        assert_eq!(
112            instance_id.id(),
113            "projects/test-project/instances/test-instance"
114        );
115    }
116
117    #[test]
118    fn test_database_id() {
119        let database_id = DatabaseId::new(
120            InstanceId::new(ProjectId::new("test-project"), "test-instance"),
121            "test-database",
122        );
123        assert_eq!(database_id.name(), "test-database");
124        assert_eq!(
125            database_id.resources_path(),
126            "projects/test-project/instances/test-instance/databases"
127        );
128        assert_eq!(
129            database_id.id(),
130            "projects/test-project/instances/test-instance/databases/test-database"
131        );
132    }
133}