public class JsonParser
{
public object Parse(string value)
{
return value.Trim() switch
{
{Length: 0} => null,
var json when json[0] == '{' && json[^1] == '}' => JsonObject(json),
var json when json[0] == '[' && json[^1] == ']' => JsonArray(json),
var json when char.IsDigit(json[0]) || json[0] == '-' => JsonNumber(json),
var json when json[0] == '"' && json[^1] == '"' => json[1..^1],
"true" => true,
"false" => false,
_ => null
};
}
private Dictionary<string, object> JsonObject(string value)
{
var jsonObject = new Dictionary<string, object>();
var elements = Token(value).ToArray();
for (var i = 0; i < elements.Length; i += 2)
{
jsonObject[elements[i][1..^1]] = Parse(elements[i + 1]);
}
return jsonObject;
}
private object[] JsonArray(string value)
{
return Token(value).Select(Parse).ToArray();
}
private object JsonNumber(string value)
{
if (value.Contains("."))
{
return double.Parse(value, NumberStyles.Float, CultureInfo.InvariantCulture);
}
return int.Parse(value, NumberStyles.Integer, CultureInfo.InvariantCulture);
}
private IEnumerable<string> Token(string value)
{
var depth = 0;
var result = new StringBuilder();
for (var i = 1; i < value.Length - 1; i++)
{
if (value[i] == '{' || value[i] == '[')
{
depth++;
}
else if (value[i] == '}' || value[i] == ']')
{
depth--;
}
else if (value[i] == '"')
{
while (i < value.Length)
{
result.Append(value[i++]);
if (value[i] == '\\' && i < value.Length - 1)
{
result.Append(value[++i]);
}
else if (value[i] == '"')
{
break;
}
}
}
else if ((value[i] == ',' || value[i] == ':') && depth == 0)
{
yield return result.ToString();
result.Clear();
}
if (!char.IsWhiteSpace(value[i]) && !((value[i] == ',' || value[i] == ':') && depth == 0))
{
result.Append(value[i]);
}
}
yield return result.ToString();
}
}-
-
Save alec1o/20fb9df4441fc8b70dcccd3632ca29bc to your computer and use it in GitHub Desktop.
Json parser in < 100 lines
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment