| author | wenzelm |
| Wed, 06 Jan 2021 13:47:50 +0100 | |
| changeset 73081 | 120ffea2c244 |
| parent 73031 | f93f0597f4fb |
| child 73712 | 3eba8d4b624b |
| permissions | -rw-r--r-- |
| 43780 | 1 |
/* Title: Pure/General/properties.scala |
2 |
Author: Makarius |
|
3 |
||
4 |
Property lists. |
|
5 |
*/ |
|
6 |
||
7 |
package isabelle |
|
8 |
||
9 |
||
10 |
object Properties |
|
11 |
{
|
|
| 65624 | 12 |
/* entries */ |
13 |
||
| 43780 | 14 |
type Entry = (java.lang.String, java.lang.String) |
15 |
type T = List[Entry] |
|
16 |
||
| 64358 | 17 |
def defined(props: T, name: java.lang.String): java.lang.Boolean = |
18 |
props.exists({ case (x, _) => x == name })
|
|
19 |
||
20 |
def get(props: T, name: java.lang.String): Option[java.lang.String] = |
|
21 |
props.collectFirst({ case (x, y) if x == name => y })
|
|
22 |
||
23 |
def put(props: T, entry: Entry): T = |
|
24 |
{
|
|
25 |
val (x, y) = entry |
|
26 |
def update(ps: T): T = |
|
27 |
ps match {
|
|
28 |
case (p @ (x1, _)) :: rest => |
|
29 |
if (x1 == x) (x1, y) :: rest else p :: update(rest) |
|
30 |
case Nil => Nil |
|
31 |
} |
|
32 |
if (defined(props, x)) update(props) else entry :: props |
|
33 |
} |
|
34 |
||
35 |
||
| 65857 | 36 |
/* external storage */ |
37 |
||
38 |
def encode(ps: T): Bytes = Bytes(YXML.string_of_body(XML.Encode.properties(ps))) |
|
39 |
||
|
73031
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
40 |
def decode(bs: Bytes, cache: XML.Cache = XML.Cache.none): T = |
|
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
41 |
cache.props(XML.Decode.properties(YXML.parse_body(bs.text))) |
| 65857 | 42 |
|
| 68018 | 43 |
def compress(ps: List[T], |
44 |
options: XZ.Options = XZ.options(), |
|
| 73024 | 45 |
cache: XZ.Cache = XZ.Cache()): Bytes = |
| 65857 | 46 |
{
|
47 |
if (ps.isEmpty) Bytes.empty |
|
| 68018 | 48 |
else {
|
49 |
Bytes(YXML.string_of_body(XML.Encode.list(XML.Encode.properties)(ps))). |
|
50 |
compress(options = options, cache = cache) |
|
51 |
} |
|
| 65857 | 52 |
} |
53 |
||
|
73031
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
54 |
def uncompress(bs: Bytes, cache: XML.Cache = XML.Cache.none): List[T] = |
| 65857 | 55 |
{
|
| 72885 | 56 |
if (bs.is_empty) Nil |
| 65857 | 57 |
else {
|
| 68018 | 58 |
val ps = |
|
73031
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
59 |
XML.Decode.list(XML.Decode.properties)( |
|
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
60 |
YXML.parse_body(bs.uncompress(cache = cache.xz).text)) |
|
f93f0597f4fb
clarified signature: absorb XZ.Cache into XML.Cache;
wenzelm
parents:
73024
diff
changeset
|
61 |
if (cache.no_cache) ps else ps.map(cache.props) |
| 65857 | 62 |
} |
63 |
} |
|
64 |
||
65 |
||
| 65624 | 66 |
/* multi-line entries */ |
67 |
||
| 65932 | 68 |
def encode_lines(props: T): T = props.map({ case (a, b) => (a, Library.encode_lines(b)) })
|
69 |
def decode_lines(props: T): T = props.map({ case (a, b) => (a, Library.decode_lines(b)) })
|
|
| 65624 | 70 |
|
71 |
def lines_nonempty(x: java.lang.String, ys: List[java.lang.String]): Properties.T = |
|
72 |
if (ys.isEmpty) Nil else List((x, cat_lines(ys))) |
|
73 |
||
74 |
||
75 |
/* entry types */ |
|
| 64358 | 76 |
|
| 43780 | 77 |
class String(val name: java.lang.String) |
78 |
{
|
|
79 |
def apply(value: java.lang.String): T = List((name, value)) |
|
80 |
def unapply(props: T): Option[java.lang.String] = |
|
81 |
props.find(_._1 == name).map(_._2) |
|
| 72137 | 82 |
def get(props: T): java.lang.String = unapply(props).getOrElse("")
|
| 43780 | 83 |
} |
84 |
||
| 48344 | 85 |
class Boolean(val name: java.lang.String) |
86 |
{
|
|
87 |
def apply(value: scala.Boolean): T = List((name, Value.Boolean(value))) |
|
88 |
def unapply(props: T): Option[scala.Boolean] = |
|
89 |
props.find(_._1 == name) match {
|
|
90 |
case None => None |
|
91 |
case Some((_, value)) => Value.Boolean.unapply(value) |
|
92 |
} |
|
| 72137 | 93 |
def get(props: T): scala.Boolean = unapply(props).getOrElse(false) |
| 48344 | 94 |
} |
95 |
||
| 48015 | 96 |
class Int(val name: java.lang.String) |
| 43780 | 97 |
{
|
98 |
def apply(value: scala.Int): T = List((name, Value.Int(value))) |
|
99 |
def unapply(props: T): Option[scala.Int] = |
|
100 |
props.find(_._1 == name) match {
|
|
101 |
case None => None |
|
102 |
case Some((_, value)) => Value.Int.unapply(value) |
|
103 |
} |
|
| 72137 | 104 |
def get(props: T): scala.Int = unapply(props).getOrElse(0) |
| 43780 | 105 |
} |
106 |
||
| 48015 | 107 |
class Long(val name: java.lang.String) |
| 43780 | 108 |
{
|
109 |
def apply(value: scala.Long): T = List((name, Value.Long(value))) |
|
110 |
def unapply(props: T): Option[scala.Long] = |
|
111 |
props.find(_._1 == name) match {
|
|
112 |
case None => None |
|
113 |
case Some((_, value)) => Value.Long.unapply(value) |
|
114 |
} |
|
| 72137 | 115 |
def get(props: T): scala.Long = unapply(props).getOrElse(0) |
| 43780 | 116 |
} |
117 |
||
| 48015 | 118 |
class Double(val name: java.lang.String) |
| 43780 | 119 |
{
|
120 |
def apply(value: scala.Double): T = List((name, Value.Double(value))) |
|
121 |
def unapply(props: T): Option[scala.Double] = |
|
122 |
props.find(_._1 == name) match {
|
|
123 |
case None => None |
|
124 |
case Some((_, value)) => Value.Double.unapply(value) |
|
125 |
} |
|
| 72137 | 126 |
def get(props: T): scala.Double = unapply(props).getOrElse(0.0) |
| 43780 | 127 |
} |
128 |
} |