1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
pub trait SpannerResource {
    fn resources_id(&self) -> String;
    fn name(&self) -> &str;
    fn id(&self) -> String {
        format!("{}/{}", self.resources_id(), self.name())
    }
    fn url_path(&self) -> String {
        format!("/v1/{}", self.id())
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct InstanceId {
    project: String,
    name: String,
}

impl InstanceId {
    pub fn new(project: &str, name: &str) -> Self {
        Self {
            project: project.to_string(),
            name: name.to_string(),
        }
    }

    pub fn project(&self) -> &str {
        &self.project
    }
}

impl SpannerResource for InstanceId {
    fn name(&self) -> &str {
        &self.name
    }

    fn resources_id(&self) -> String {
        format!("projects/{}/instances", self.project)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DatabaseId(InstanceId, String);
impl DatabaseId {
    pub fn new(instance: InstanceId, name: &str) -> Self {
        Self(instance, name.to_string())
    }
}

impl SpannerResource for DatabaseId {
    fn name(&self) -> &str {
        &self.1
    }

    fn resources_id(&self) -> String {
        format!("{}/databases", self.0.id())
    }
}

#[cfg(test)]
mod test {
    use super::{DatabaseId, InstanceId, SpannerResource};

    #[test]
    fn test_instance_id() {
        let instance_id = InstanceId::new("test-project", "test-instance");
        assert_eq!(instance_id.name(), "test-instance");
        assert_eq!(
            instance_id.resources_id(),
            "projects/test-project/instances"
        );
        assert_eq!(
            instance_id.id(),
            "projects/test-project/instances/test-instance"
        );
        assert_eq!(
            instance_id.url_path(),
            "/v1/projects/test-project/instances/test-instance"
        );
    }

    #[test]
    fn test_database_id() {
        let database_id = DatabaseId::new(
            InstanceId::new("test-project", "test-instance"),
            "test-database",
        );
        assert_eq!(database_id.name(), "test-database");
        assert_eq!(
            database_id.resources_id(),
            "projects/test-project/instances/test-instance/databases"
        );
        assert_eq!(
            database_id.id(),
            "projects/test-project/instances/test-instance/databases/test-database"
        );
        assert_eq!(
            database_id.url_path(),
            "/v1/projects/test-project/instances/test-instance/databases/test-database"
        );
    }
}