@@ -71,21 +71,32 @@ object Access {
71
71
72
72
def (x : Permissions ) & (y : Permissions ): Permissions = x | y
73
73
def (x : PermissionChoice ) | (y : PermissionChoice ): PermissionChoice = x | y
74
- def (x : Permissions ).is(y : Permissions ) = (x & y ) == y
75
- def (x : Permissions ).isOneOf(y : PermissionChoice ) = (x & y ) != 0
74
+ def (granted : Permissions ).is(required : Permissions ) = (granted & required ) == required
75
+ def (granted : Permissions ).isOneOf(required : PermissionChoice ) = (granted & required ) != 0
76
76
77
77
val NoPermission : Permission = 0
78
- val ReadOnly : Permission = 1
79
- val WriteOnly : Permission = 2
80
- val ReadWrite : Permissions = ReadOnly & WriteOnly
81
- val ReadOrWrite : PermissionChoice = ReadOnly | WriteOnly
78
+ val Read : Permission = 1
79
+ val Write : Permission = 2
80
+ val ReadWrite : Permissions = Read | Write
81
+ val ReadOrWrite : PermissionChoice = Read | Write
82
82
}
83
83
```
84
84
The ` Access ` object defines three opaque types:
85
85
86
86
- ` Permission ` , representing a single permission,
87
- - ` Permissions ` , representing a conjunction (logical "and") of permissions,
88
- - ` PermissionChoice ` , representing a disjunction (logical "or") of permissions.
87
+ - ` Permissions ` , representing a set of permissions with the meaning "all of these permissions granted",
88
+ - ` PermissionChoice ` , representing a set of permissions with the meaning "at least one of these permissions granted".
89
+
90
+ Outside the ` Access ` object, values of type ` Permissions ` may be combined using the ` & ` operator,
91
+ where ` x & y ` means "all permissions in ` x ` * and* in ` y ` granted".
92
+ Values of type ` PermissionChoice ` may be combined using the ` | ` operator,
93
+ where ` x | y ` means "a permission in ` x ` * or* in ` y ` granted".
94
+
95
+ Note that inside the ` Access ` object, the ` & ` and ` | ` operators always resolve to the corresponding methods of ` Int ` ,
96
+ because members always take precedence over extension methods.
97
+ Because of that, the ` | ` extension method in ` Access ` does not cause infinite recursion.
98
+ Also, the definition of ` ReadWrite ` must use ` | ` ,
99
+ even though an equivalent definition outside ` Access ` would use ` & ` .
89
100
90
101
All three opaque types have the same underlying representation type ` Int ` . The
91
102
` Permission ` type has an upper bound ` Permissions & PermissionChoice ` . This makes
@@ -97,13 +108,21 @@ object User {
97
108
98
109
case class Item (rights : Permissions )
99
110
100
- val x = Item (ReadOnly ) // OK, since Permission <: Permissions
111
+ val roItem = Item (Read ) // OK, since Permission <: Permissions
112
+ val rwItem = Item (ReadWrite )
113
+ val noItem = Item (NoPermission )
114
+
115
+ assert( roItem.rights.is(ReadWrite ) == false )
116
+ assert( roItem.rights.isOneOf(ReadOrWrite ) == true )
117
+
118
+ assert( rwItem.rights.is(ReadWrite ) == true )
119
+ assert( rwItem.rights.isOneOf(ReadOrWrite ) == true )
101
120
102
- assert( x .rights.is(ReadWrite ) == false )
103
- assert( x .rights.isOneOf(ReadOrWrite ) == true )
121
+ assert( noItem .rights.is(ReadWrite ) == false )
122
+ assert( noItem .rights.isOneOf(ReadOrWrite ) == false )
104
123
}
105
124
```
106
- On the other hand, the call ` x .rights.isOneOf(ReadWrite)` would give a type error
125
+ On the other hand, the call ` roItem .rights.isOneOf(ReadWrite)` would give a type error
107
126
since ` Permissions ` and ` PermissionChoice ` are different, unrelated types outside ` Access ` .
108
127
109
128
[ More details] ( opaques-details.md )
0 commit comments