Created
October 17, 2013 16:56
-
-
Save jmarnold/7028432 to your computer and use it in GitHub Desktop.
Improved JObjectValues
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class JObjectValues : IValueSource | |
{ | |
private readonly JObject _jObject; | |
public JObjectValues(string json) | |
: this(JObject.Parse(json)) | |
{ | |
} | |
public JObjectValues(JObject jObject) | |
{ | |
_jObject = jObject; | |
} | |
private bool with<T>(string key, Action<T> action) where T : JToken | |
{ | |
JToken token = null; | |
_jObject.TryGetValue(key, out token); | |
var target = token as T; | |
if (target != null) | |
{ | |
action(target); | |
return true; | |
} | |
return false; | |
} | |
private TReturn find<T, TReturn>(string key, Func<T, TReturn> creator) | |
where T : JToken | |
where TReturn : class | |
{ | |
JToken token = null; | |
_jObject.TryGetValue(key, out token); | |
var specific = token as T; | |
return specific == null ? null : creator(specific); | |
} | |
public bool Has(string key) | |
{ | |
return with<JValue>(key, x => { }) || with<JObject>(key, x => { }); | |
} | |
public object Get(string key) | |
{ | |
return find<JValue, object>(key, v => v.Value<string>()); | |
} | |
public bool HasChild(string key) | |
{ | |
return with<JObject>(key, o => { }); | |
} | |
public IValueSource GetChild(string key) | |
{ | |
return find<JObject, IValueSource>(key, x => new JObjectValues(x)); | |
} | |
public IEnumerable<IValueSource> GetChildren(string key) | |
{ | |
Func<JArray, IEnumerable<IValueSource>> creator = ja => ja.OfType<JObject>().Select(x => new JObjectValues(x)).ToList(); | |
return find(key, creator) ?? Enumerable.Empty<IValueSource>(); | |
} | |
public void WriteReport(IValueReport report) | |
{ | |
foreach (var pair in _jObject) | |
{ | |
var key = pair.Key; | |
pair.IfIs<JValue>(value => report.Value(key, value.Value<string>())); | |
pair.IfIs<JObject>(jo => | |
{ | |
report.StartChild(key); | |
var child = new JObjectValues(jo); | |
child.WriteReport(report); | |
report.EndChild(); | |
}); | |
pair.IfIs<JArray>(ja => | |
{ | |
int i = 0; | |
foreach (JObject jo in ja.OfType<JObject>()) | |
{ | |
report.StartChild(key, i); | |
var child = new JObjectValues(jo); | |
child.WriteReport(report); | |
report.EndChild(); | |
} | |
}); | |
} | |
} | |
public bool Value(string key, Action<BindingValue> callback) | |
{ | |
var found = with<JValue>(key, v => callback(new BindingValue | |
{ | |
RawKey = key, | |
RawValue = v.Value<string>(), | |
Source = Provenance | |
})); | |
if (found) return true; | |
return with<JObject>(key, v => callback(new BindingValue | |
{ | |
RawKey = key, | |
RawValue = v, | |
Source = Provenance | |
})); | |
} | |
public string Provenance | |
{ | |
get { return "Json Values"; } | |
} | |
} | |
public static class JTokenKeyValuePairExtensions | |
{ | |
public static void IfIs<T>(this KeyValuePair<string, JToken> pair, Action<T> action) where T : class | |
{ | |
var target = pair.Value as T; | |
if (target != null) | |
{ | |
action(target); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment