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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::{Entity, Relation, Resource, Subject};

use super::subject_filter::RelationFilter;
use super::{ObjectReference, Precondition, RelationshipFilter, SubjectFilter, SubjectReference};

pub fn subject_filter<S>(id: Option<S::Id>, relation: Option<S::Relations>) -> SubjectFilter
where
    S: Subject,
{
    subject_filter_raw(S::object_type(), id, relation.map(|r| r.name()))
}

pub fn subject_filter_raw(
    subject_type: impl Into<String>,
    id: Option<impl Into<String>>,
    relation: Option<impl Into<String>>,
) -> SubjectFilter {
    SubjectFilter {
        subject_type: subject_type.into(),
        optional_subject_id: id.map(Into::into).unwrap_or_default(),
        optional_relation: relation.map(|r| RelationFilter { relation: r.into() }),
    }
}

pub fn relationship_filter<R>(
    resource_id: Option<R::Id>,
    resource_id_prefix: Option<String>,
    relation: Option<R::Relations>,
    subject_filter: Option<SubjectFilter>,
) -> RelationshipFilter
where
    R: Resource,
{
    relationship_filter_raw(
        R::object_type(),
        resource_id,
        resource_id_prefix,
        relation.map(|r| r.name()),
        subject_filter,
    )
}

pub fn relationship_filter_raw(
    resource_type: impl Into<String>,
    resource_id: Option<impl Into<String>>,
    resource_id_prefix: Option<impl Into<String>>,
    relation: Option<impl Into<String>>,
    subject_filter: Option<SubjectFilter>,
) -> RelationshipFilter {
    RelationshipFilter {
        resource_type: resource_type.into(),
        optional_resource_id: resource_id.map(Into::into).unwrap_or_default(),
        optional_resource_id_prefix: resource_id_prefix.map(Into::into).unwrap_or_default(),
        optional_relation: relation.map(Into::into).unwrap_or_default(),
        optional_subject_filter: subject_filter,
    }
}

pub fn precondition<R>(
    operation: super::precondition::Operation,
    resource_id: Option<R::Id>,
    resource_id_prefix: Option<String>,
    relation: Option<R::Relations>,
    subject_filter: Option<SubjectFilter>,
) -> Precondition
where
    R: Resource,
{
    precondition_raw(
        operation,
        R::object_type(),
        resource_id,
        resource_id_prefix,
        relation.map(|r| r.name()),
        subject_filter,
    )
}

pub fn precondition_raw(
    operation: super::precondition::Operation,
    resource_type: impl Into<String>,
    resource_id: Option<impl Into<String>>,
    resource_id_prefix: Option<impl Into<String>>,
    relation: Option<impl Into<String>>,
    subject_filter: Option<SubjectFilter>,
) -> Precondition {
    Precondition {
        operation: operation as i32,
        filter: Some(relationship_filter_raw(
            resource_type,
            resource_id,
            resource_id_prefix,
            relation,
            subject_filter,
        )),
    }
}

pub fn subject_reference<S>(id: S::Id, relation: Option<S::Relations>) -> SubjectReference
where
    S: Subject,
{
    subject_reference_raw(id, S::object_type(), relation.map(|r| r.name()))
}

pub fn subject_reference_raw(
    id: impl Into<String>,
    object_type: impl Into<String>,
    relation: Option<impl Into<String>>,
) -> SubjectReference {
    SubjectReference {
        object: Some(ObjectReference {
            object_type: object_type.into(),
            object_id: id.into(),
        }),
        optional_relation: relation.map(Into::into).unwrap_or_default(),
    }
}

pub fn object_reference<E>(id: E::Id) -> ObjectReference
where
    E: Entity,
{
    ObjectReference {
        object_type: E::object_type().into(),
        object_id: id.into(),
    }
}