protected IResult <Unit> serializeValue(string name, object value) { var lName = name.ToLower1(); if (value.IsNull()) { builder.Add(lName); } else { var type = value.GetType(); switch (value) { case bool b: builder.Add(lName, b); break; case string s: builder.Add(lName, s); break; case int i: builder.Add(lName, i); break; case double d: builder.Add(lName, d); break; case byte[] ba: builder.Add(lName, ba); break; case FileName file: builder.Add(lName, file); break; case FolderName folder: builder.Add(lName, folder); break; default: if (type.IsEnum) { builder.Add(lName, (Enum)value); } else { switch (value) { case Guid g: builder.Add(lName, g); break; case TimeSpan ts: builder.Add(lName, ts); break; default: if (type.IsArray) { var objArray = (Array)value; builder.BeginArray(lName); foreach (var result in objArray.Cast <object>().Select(serializeValue).Where(result => result.IsFailed)) { return(result); } builder.End(); } else { var result = serializeObject(lName, value); if (result.IsFailed) { return(result); } } break; } } break; } } return(Unit.Success()); }
protected IResult <Unit> parseValue(string name) { var anyTokenType = lookAhead(); if (anyTokenType.ValueOrCast <Unit>(out var tokenType, out var original)) { switch (tokenType) { case TokenType.Number: if (parseNumber(name).ValueOrCast(out var number, out original)) { switch (number) { case double d: builder.Add(name, d); return(Unit.Success()); case int i: builder.Add(name, i); return(Unit.Success()); default: return($"Couldn't determine number type of {number}".Failure <Unit>()); } } else { return(original); } case TokenType.String: if (parseString(name, '"').ValueOrCast(out var s, out original)) { builder.Add(name, s); return(Unit.Success()); } else { return(original); } case TokenType.StringSingle: if (parseString(name, '\'').ValueOrCast(out s, out original)) { builder.Add(name, s); return(Unit.Success()); } else { return(original); } case TokenType.ObjectOpen: return(parseObject(name)); case TokenType.ArrayOpen: return(parseArray(name)); case TokenType.True: setLookAheadTokenToNone(); builder.Add(name, true); invokeEvent(TokenType.True, name, "true"); return(Unit.Success()); case TokenType.False: setLookAheadTokenToNone(); builder.Add(name, false); invokeEvent(TokenType.False, name, "false"); return(Unit.Success()); case TokenType.Null: setLookAheadTokenToNone(); builder.Add(name); invokeEvent(TokenType.Null, name, "null"); return(Unit.Success()); default: return($"Didn't understand token at {index}".Failure <Unit>()); } } else { return(original); } }