private static IEnumerable <Json> StrIndicesImpl( List <IJsonMasherOperator> mashers, Json haystack, IMashContext context) { if (haystack == null || haystack.Type != JsonValueType.String) { throw context.Error($"_strindices: cannot index over {haystack?.Type}.", haystack); } foreach (var needle in mashers[0].Mash(haystack, context)) { if (needle == null || needle.Type != JsonValueType.String) { throw context.Error($"_strindices: cannot index over {needle?.Type}.", needle); } var result = new List <Json>(); int start = 0; while (start >= 0) { start = haystack.GetString().IndexOf(needle.GetString(), start); if (start >= 0) { result.Add(Json.Number(start)); start++; } } yield return(Json.Array(result)); } }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.String) { throw context.Error($"The input must be a string, not {json?.Type}.", json); } foreach (var regex in mashers[0].Mash(json, context)) { if (regex == null || regex.Type != JsonValueType.String) { throw context.Error($"The regex must be a string, not {regex?.Type}.", regex); } foreach (var flags in mashers[1].Mash(json, context)) { string flagsValue = flags.Type == JsonValueType.String ? flags.GetString() : ""; foreach (var onlyTest in mashers[2].Mash(json, context)) { var matches = GetMatches( json.GetString(), regex.GetString(), flagsValue, onlyTest.GetBool()); foreach (var match in matches) { yield return(match); } } } } }
private static IEnumerable <Json> Strptime_Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.String) { throw context.Error( $"strptime: need string representing a date, not {json?.Type}.", json); } foreach (var formatString in mashers[0].Mash(json, context)) { if (formatString == null || formatString.Type != JsonValueType.String) { throw context.Error( $"strptime: need a format string, not {formatString?.Type}.", formatString); } if (DateTimeOffset.TryParseExact( json.GetString(), formatString.GetString(), null, DateTimeStyles.None, out var result)) { yield return(Json.Number((result - _epoch).TotalSeconds)); } else { throw context.Error( $"strptime: Can't parse '{json.GetString()}' using '{formatString.GetString()}'.", json, formatString); } } }
private static IEnumerable <Json> Function_1( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json.Type == JsonValueType.Array) { var masher = mashers.First(); var keys = masher.Mash(json, context).FirstOrDefault(); if (keys == null || keys.Type != JsonValueType.Array) { return(Json.Array(json.EnumerateArray().OrderBy(x => x, JsonComparer.Instance)) .AsEnumerable()); } else { var values = json .EnumerateArray() .Zip(keys.EnumerateArray(), (v, k) => Tuple.Create(v, k)) .OrderBy(x => x.Item2, JsonComparer.Instance) .Select(x => x.Item1); return(Json.Array(values).AsEnumerable()); } } else { throw context.Error($"Can't sort a {json.Type}.", json); } }
private static IEnumerable <Json> FromDate_Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.String) { throw context.Error($"fromdateiso8601: Need a string, not {json?.Type}.", json); } if (DateTimeOffset.TryParse(json.GetString(), out var result)) { yield return(Json.Number((result - _epoch).TotalSeconds)); } else { throw context.Error($"fromdateiso8601: Can't parse '{json.GetString()}' as ISO 8601 date.", json); } }
private static Json DeletePath(Json json, JsonPath path, IMashContext context) => json.TransformByPath( path, leafJson => null, (json, pathPart) => context.Error( $"Can't index {json.Type} with {pathPart.ToString()}.", json, pathPart.ToJson()));
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.Array) { throw context.Error($"Need an array of numbers to implode, not {json?.Type}.", json); } var sb = new StringBuilder(); foreach (var value in json.EnumerateArray()) { if (value == null || value.Type != JsonValueType.Number) { throw context.Error($"Needed a number, but got {value?.Type}.", value); } sb.Append(((char)(int)value.GetNumber()).ToString()); } yield return(Json.String(sb.ToString())); }
private static void EnsureNumber(Json value, IMashContext context, string functionName) { if (value != null && value.Type == JsonValueType.Number) { return; } throw context.Error( $"Function {functionName} must be applied to numbers, not {value?.Type}.", value); }
public static Json HasIndex(Json json, Json index, IMashContext context) { return((json.Type, index.Type) switch { (JsonValueType.Array, JsonValueType.Number) => Json.Bool(json.ContainsKey((int)index.GetNumber())), (JsonValueType.Object, JsonValueType.String) => Json.Bool(json.ContainsKey(index.GetString())), _ => throw context.Error( $"Can't index {json.Type} with {index.Type}.", json, index) });
private static IEnumerable <Json> Strftime_Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.Number) { throw context.Error( $"strftime: need a number of seconds, not {json?.Type}.", json); } foreach (var formatString in mashers[0].Mash(json, context)) { if (formatString == null || formatString.Type != JsonValueType.String) { throw context.Error( $"strftime: need a format string, not {formatString?.Type}.", formatString); } var date = _epoch.AddSeconds(json.GetNumber()); var result = date.ToString(formatString.GetString(), CultureInfo.InvariantCulture); yield return(Json.String(result)); } }
private static IEnumerable <Json> ToDate_Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json == null || json.Type != JsonValueType.Number) { throw context.Error($"todateiso8601: Need a number, not {json?.Type}.", json); } var date = _epoch.AddSeconds(json.GetNumber()); yield return(Json.String(date.ToString("o", CultureInfo.InvariantCulture))); }
private static IEnumerable <Json> Function_0( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { if (json.Type == JsonValueType.Array) { return(Json.Array(json.EnumerateArray().OrderBy(x => x, JsonComparer.Instance)) .AsEnumerable()); } else { throw context.Error($"Can't sort a {json.Type}.", json); } }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { foreach (var value in mashers[0].Mash(json, context)) { yield return((json.Type, value.Type) switch { (JsonValueType.String, JsonValueType.String) => Json.Bool(json.GetString().IndexOf(value.GetString()) != -1), (JsonValueType.Array, JsonValueType.Array) => Json.Bool(ArrayContains(json, value)), (JsonValueType.Object, JsonValueType.Object) => Json.Bool(ObjectContains(json, value)), _ => throw context.Error($"Can't check if {json.Type} contains {value.Type}.", json, value) });
public static IEnumerable <Json> ExtractMinMax( List <IJsonMasherOperator> mashers, Json json, IMashContext context, bool min) { if (json == null || json.Type != JsonValueType.Array) { throw context.Error( $"Cannot find minimum for {json?.Type}, need an array.", json); } var keys = mashers[0].Mash(json, context).FirstOrDefault(); if (keys == null || keys.Type != JsonValueType.Array) { throw context.Error( $"Cannot find minimum with {json?.Type} as keys, need an array.", keys); } var query = json.EnumerateArray() .Zip(keys.EnumerateArray(), (v, k) => Tuple.Create(k, v)); if (min) { query = query.OrderBy(x => x.Item1, JsonComparer.Instance); // there is no MinBy... } else { query = query.OrderByDescending(x => x.Item1, JsonComparer.Instance); // there is no MaxBy... } var value = query.Take(1).Select(x => x.Item2).FirstOrDefault(); if (value == null) { return(Json.Null.AsEnumerable()); } else { return(value.AsEnumerable()); } }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { foreach (var limitValue in mashers[0].Mash(json, context)) { if (limitValue.Type != JsonValueType.Number) { throw context.Error($"Can't use {limitValue.Type} as limit.", limitValue); } int limit = (int)limitValue.GetNumber(); foreach (var result in mashers[1].Mash(json, context).Take(limit)) { yield return(result); } } }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { foreach (var value in mashers[1].Mash(json, context)) { foreach (var pathAsJson in mashers[0].Mash(json, context)) { var path = context.GetPathFromArray(pathAsJson); yield return(json.TransformByPath( path, leafJson => value, (json, pathPart) => context.Error( $"Can't index {json.Type} with {pathPart.ToString()}.", json, pathPart.ToJson()))); } } }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { var result = new List <Json>(); foreach (var pathAsJson in mashers[0].Mash(json, context)) { var path = context.GetPathFromArray(pathAsJson); json.TransformByPath( path, leafJson => { result.Add(leafJson); return(leafJson); }, (json, pathPart) => context.Error( $"Can't index {json.Type} with {pathPart.ToString()}.", json, pathPart.ToJson())); } return(result); }
private static IEnumerable <Json> Function( List <IJsonMasherOperator> mashers, Json json, IMashContext context) { foreach (var jsonPaths in mashers[0].Mash(json, context)) { if (jsonPaths.Type != JsonValueType.Array) { throw context.Error($"Expected an array of paths.", jsonPaths); } var paths = jsonPaths .EnumerateArray() .OrderByDescending(x => x, JsonComparer.Instance) .Select(x => context.GetPathFromArray(x)); var jsonResult = json; foreach (var path in paths) { jsonResult = DeletePath(jsonResult, path, context); } yield return(jsonResult); } }