-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFirebasePriority.cs
executable file
·195 lines (174 loc) · 5.79 KB
/
FirebasePriority.cs
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
using System;
using System.Diagnostics;
using Newtonsoft.Json.Linq;
namespace FirebaseDotNetCore
{
public enum PriorityType
{
None,
String,
Numeric
}
public class FirebasePriority
{
public PriorityType Type { get; private set; }
private readonly float? _fp;
private readonly string _sp;
internal FirebasePriority(JValue priority)
{
if (priority == null || priority.Type == JTokenType.Null)
{
Type = PriorityType.None;
return;
}
switch (priority.Type)
{
case JTokenType.None:
Type = PriorityType.None;
return;
case JTokenType.Integer:
case JTokenType.Float:
Type = PriorityType.Numeric;
_fp = priority.Value<float>();
return;
case JTokenType.String:
int value;
if (int.TryParse(priority.Value<string>(), out value))
{
Type = PriorityType.Numeric;
_fp = value;
}
else
{
Type = PriorityType.String;
_sp = priority.Value<string>();
}
return;
default:
throw new Exception(string.Format("Unable to load priority of type: {0}", priority.Type));
}
}
public FirebasePriority(string priority)
{
if (priority == null)
{
Type = PriorityType.None;
}
else
{
Type = PriorityType.String;
_sp = priority;
}
}
public FirebasePriority(float priority)
{
Type = PriorityType.Numeric;
_fp = priority;
}
public FirebasePriority(long priority)
{
Type = PriorityType.Numeric;
_fp = priority;
}
/*
* Children with no priority (the default) come first.
* Children with a number as their priority come next.
* They are sorted numerically by priority, small to large.
* Children with a string as their priority come last.
* They are sorted lexicographically by priority.
* Whenever two children have the same priority (including no priority),
* they are sorted by key. Numeric keys come first (sorted numerically),
* followed by the remaining keys (sorted lexicographically).
*/
public int CompareTo(FirebasePriority other)
{
// Children with no priority (the default) come first.
if (Type == PriorityType.None)
{
if (other.Type == PriorityType.None)
{
return 0;
}
return -1;
}
else if (other.Type == PriorityType.None)
{
return 1;
}
// Children with a number as their priority come next.
if (Type == PriorityType.Numeric)
{
if (other.Type == PriorityType.Numeric)
{
if (_fp.HasValue && other._fp.HasValue)
{
return _fp.Value.CompareTo(other._fp.Value);
}
throw new Exception("Priority is a numeric but value not set");
}
return -1;
}
else if (other.Type == PriorityType.Numeric)
{
return 1;
}
// Children with a string as their priority come last.
if (Type == PriorityType.String)
{
if (other.Type == PriorityType.String)
{
if (_sp != null && other._sp != null)
{
return String.Compare(_sp, other._sp, StringComparison.Ordinal);
}
throw new Exception("Priority is a string but value not set");
}
// will throw in a moment in release builds
Debug.Assert(false, "It should not be possible for both to not be strings at this point");
}
else if (other.Type == PriorityType.String)
{
return 1;
}
throw new Exception("Priority sorting did not detect a valid state");
}
public string JsonValue
{
get
{
switch (Type)
{
case PriorityType.None:
return "null";
case PriorityType.Numeric:
return _fp.ToString();
case PriorityType.String:
return string.Format("\"{0}\"", _sp);
default:
throw new InvalidOperationException("Unknown format type: {0}" + Type);
}
}
}
public string Value
{
get
{
switch (Type)
{
case PriorityType.None:
return null;
case PriorityType.Numeric:
return _fp.ToString();
case PriorityType.String:
return _sp;
default:
throw new InvalidOperationException("Unknown format type: {0}" + Type);
}
}
}
public override string ToString()
{
return Value;
}
}
}