-
Notifications
You must be signed in to change notification settings - Fork 20
/
Vault.scala
85 lines (76 loc) · 2.2 KB
/
Vault.scala
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
package io.chrisdavenport.vault
import io.chrisdavenport.unique.Unique
/**
* Vault - A persistent store for values of arbitrary types.
* This extends the behavior of the locker, into a Map
* that maps Keys to Lockers, creating a heterogenous
* store of values, accessible by keys. Such that the Vault
* has no type information, all the type information is contained
* in the keys.
*/
final class Vault private (private val m: Map[Unique, Locker]) {
/**
* Empty this Vault
*/
def empty : Vault = Vault.empty
/**
* Lookup the value of a key in this vault
*/
def lookup[A](k: Key[A]): Option[A] = Vault.lookup(k, this)
/**
* Insert a value for a given key. Overwrites any previous value.
*/
def insert[A](k: Key[A], a: A): Vault = Vault.insert(k, a, this)
/**
* Checks whether this Vault is empty
*/
def isEmpty: Boolean = Vault.isEmpty(this)
/**
* Delete a key from the vault
*/
def delete[A](k: Key[A]): Vault = Vault.delete(k, this)
/**
* Adjust the value for a given key if it's present in the vault.
*/
def adjust[A](k: Key[A], f: A => A): Vault = Vault.adjust(k, f, this)
/**
* Merge Two Vaults. that is prioritized.
*/
def ++(that: Vault): Vault = Vault.union(this, that)
}
object Vault {
/**
* The Empty Vault
*/
def empty = new Vault(Map.empty)
/**
* Lookup the value of a key in the vault
*/
def lookup[A](k: Key[A], v: Vault): Option[A] =
v.m.get(k.unique).flatMap(Locker.unlock(k, _))
/**
* Insert a value for a given key. Overwrites any previous value.
*/
def insert[A](k: Key[A], a: A, v: Vault): Vault =
new Vault(v.m + (k.unique -> Locker.lock(k, a)))
/**
* Checks whether the given Vault is empty
*/
def isEmpty(v: Vault): Boolean =
v.m.isEmpty
/**
* Delete a key from the vault
*/
def delete[A](k: Key[A], v: Vault): Vault =
new Vault(v.m - k.unique)
/**
* Adjust the value for a given key if it's present in the vault.
*/
def adjust[A](k: Key[A], f: A => A, v: Vault): Vault =
lookup(k, v).fold(v)(a => insert(k, f(a), v))
/**
* Merge Two Vaults. v2 is prioritized.
*/
def union(v1: Vault, v2: Vault): Vault =
new Vault(v1.m ++ v2.m)
}