///`authz` type for a resource of type InstanceUsed to uniquely identify a resource of type Instance across renames, moves, etc., and to do authorization checks (see  [`crate::context::OpContext::authorize()`]).  See [`crate::authz`] module-level documentation for more information.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Instance {
    parent: Project,
    key: (String, String),
    lookup_type: LookupType,
}
impl Instance {
    /// Makes a new `authz` struct for this resource with the given
    /// `parent`, unique key `key`, looked up as described by
    /// `lookup_type`
    pub fn new(
        parent: Project,
        key: SomeCompositeId,
        lookup_type: LookupType,
    ) -> Instance {
        Instance {
            parent,
            key: key.into(),
            lookup_type,
        }
    }
    /// A version of `new` that takes the primary key type directly.
    /// This is only different from [`Self::new`] if this resource
    /// uses a different input key type.
    pub fn with_primary_key(
        parent: Project,
        key: (String, String),
        lookup_type: LookupType,
    ) -> Instance {
        Instance {
            parent,
            key,
            lookup_type,
        }
    }
    pub fn id(&self) -> (String, String) {
        self.key.clone().into()
    }
    /// Describes how to register this type with Oso
    pub(super) fn init() -> Init {
        use oso::PolarClass;
        Init {
            polar_snippet: "\n                resource Instance {\n                    permissions = [\n                        \"list_children\",\n                        \"modify\",\n                        \"read\",\n                        \"create_child\",\n                    ];\n\n                    relations = { containing_project: Project };\n                    \"list_children\" if \"viewer\" on \"containing_project\";\n                    \"read\" if \"viewer\" on \"containing_project\";\n                    \"modify\" if \"limited-collaborator\" on \"containing_project\";\n                    \"create_child\" if \"limited-collaborator\" on \"containing_project\";\n                }\n\n                has_relation(parent: Project, \"containing_project\", child: Instance)\n                        if child.project = parent;\n            ",
            polar_class: Instance::get_polar_class(),
        }
    }
}
impl Eq for Instance {}
impl PartialEq for Instance {
    fn eq(&self, other: &Self) -> bool {
        self.key == other.key
    }
}
impl oso::PolarClass for Instance {
    fn get_polar_class_builder() -> oso::ClassBuilder<Self> {
        oso::Class::builder()
            .with_equality_check()
            .add_method(
                "has_role",
                |r: &Instance, actor: AuthenticatedActor, role: String| { false },
            )
            .add_attribute_getter("project", |r: &Instance| r.parent.clone())
    }
}
impl ApiResource for Instance {
    fn parent(&self) -> Option<&dyn AuthorizedResource> {
        Some(&self.parent)
    }
    fn resource_type(&self) -> ResourceType {
        ResourceType::Instance
    }
    fn lookup_type(&self) -> &LookupType {
        &self.lookup_type
    }
    fn as_resource_with_roles(&self) -> Option<&dyn ApiResourceWithRoles> {
        None
    }
}
