public static object parseSpan(ReadOnlySpan <char> json) { if (json.Length == 0) { return(null); } var firstChar = json[0]; bool isEscapedJsonString(ReadOnlySpan <char> js) => js.StartsWith(@"{\") || js.StartsWith(@"[{\"); if (firstChar >= '0' && firstChar <= '9') { try { var longValue = MemoryProvider.Instance.ParseInt64(json); return(longValue >= int.MinValue && longValue <= int.MaxValue ? (int)longValue : longValue); } catch {} if (json.TryParseDouble(out var doubleValue)) { return(doubleValue); } } else if (firstChar == '{' || firstChar == '[' && !isEscapedJsonString(json.TrimStart())) { json.ParseJsToken(out var token); return(token.Evaluate(JS.CreateScope())); } else if (json.Length == 4) { if (firstChar == 't' && json[1] == 'r' && json[2] == 'u' && json[3] == 'e') { return(true); } if (firstChar == 'n' && json[1] == 'u' && json[2] == 'l' && json[3] == 'l') { return(null); } } else if (json.Length == 5 && firstChar == 'f' && json[1] == 'a' && json[2] == 'l' && json[3] == 's' && json[4] == 'e') { return(false); } var unescapedString = JsonTypeSerializer.Unescape(json); return(unescapedString.ToString()); }
private static ParseStringSpanDelegate GetParseStringSpanFn() { var nullableType = Nullable.GetUnderlyingType(typeof(T)); if (nullableType == null) { var typeCode = typeof(T).GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: return(value => value.ParseBoolean()); case TypeCode.SByte: return(SignedInteger <sbyte> .ParseObject); case TypeCode.Byte: return(UnsignedInteger <byte> .ParseObject); case TypeCode.Int16: return(SignedInteger <short> .ParseObject); case TypeCode.UInt16: return(UnsignedInteger <ushort> .ParseObject); case TypeCode.Int32: return(SignedInteger <int> .ParseObject); case TypeCode.UInt32: return(UnsignedInteger <uint> .ParseObject); case TypeCode.Int64: return(SignedInteger <long> .ParseObject); case TypeCode.UInt64: return(UnsignedInteger <ulong> .ParseObject); case TypeCode.Single: return(value => MemoryProvider.Instance.ParseFloat(value)); case TypeCode.Double: return(value => MemoryProvider.Instance.ParseDouble(value)); case TypeCode.Decimal: return(value => MemoryProvider.Instance.ParseDecimal(value)); case TypeCode.DateTime: return(value => DateTimeSerializer.ParseShortestXsdDateTime(value.ToString())); case TypeCode.Char: return(value => value.Length == 0 ? (char)0 : value.Length == 1 ? value[0] : JsonTypeSerializer.Unescape(value)[0]); } if (typeof(T) == typeof(Guid)) { return(value => value.ParseGuid()); } if (typeof(T) == typeof(DateTimeOffset)) { return(value => DateTimeSerializer.ParseDateTimeOffset(value.ToString())); } if (typeof(T) == typeof(TimeSpan)) { return(value => DateTimeSerializer.ParseTimeSpan(value.ToString())); } #if NET6_0 if (typeof(T) == typeof(DateOnly)) { return(value => DateOnly.FromDateTime(DateTimeSerializer.ParseShortestXsdDateTime(value.ToString()))); } if (typeof(T) == typeof(TimeOnly)) { return(value => TimeOnly.FromTimeSpan(DateTimeSerializer.ParseTimeSpan(value.ToString()))); } #endif } else { var typeCode = nullableType.GetTypeCode(); switch (typeCode) { case TypeCode.Boolean: return(value => value.IsNullOrEmpty() ? (bool?)null : value.ParseBoolean()); case TypeCode.SByte: return(SignedInteger <sbyte> .ParseNullableObject); case TypeCode.Byte: return(UnsignedInteger <byte> .ParseNullableObject); case TypeCode.Int16: return(SignedInteger <short> .ParseNullableObject); case TypeCode.UInt16: return(UnsignedInteger <ushort> .ParseNullableObject); case TypeCode.Int32: return(SignedInteger <int> .ParseNullableObject); case TypeCode.UInt32: return(UnsignedInteger <uint> .ParseNullableObject); case TypeCode.Int64: return(SignedInteger <long> .ParseNullableObject); case TypeCode.UInt64: return(UnsignedInteger <ulong> .ParseNullableObject); case TypeCode.Single: return(value => value.IsNullOrEmpty() ? (float?)null : value.ParseFloat()); case TypeCode.Double: return(value => value.IsNullOrEmpty() ? (double?)null : value.ParseDouble()); case TypeCode.Decimal: return(value => value.IsNullOrEmpty() ? (decimal?)null : value.ParseDecimal()); case TypeCode.DateTime: return(value => DateTimeSerializer.ParseShortestNullableXsdDateTime(value.ToString())); case TypeCode.Char: return(value => value.IsEmpty ? (char?)null : value.Length == 1 ? value[0] : JsonTypeSerializer.Unescape(value)[0]); } if (typeof(T) == typeof(TimeSpan?)) { return(value => DateTimeSerializer.ParseNullableTimeSpan(value.ToString())); } if (typeof(T) == typeof(Guid?)) { return(value => value.IsNullOrEmpty() ? (Guid?)null : value.ParseGuid()); } if (typeof(T) == typeof(DateTimeOffset?)) { return(value => DateTimeSerializer.ParseNullableDateTimeOffset(value.ToString())); } #if NET6_0 if (typeof(T) == typeof(DateOnly?)) { return(value => value.IsNullOrEmpty() ? default : DateOnly.FromDateTime(DateTimeSerializer.ParseShortestXsdDateTime(value.ToString()))); } if (typeof(T) == typeof(TimeOnly?)) { return(value => value.IsNullOrEmpty() ? default : TimeOnly.FromTimeSpan(DateTimeSerializer.ParseTimeSpan(value.ToString()))); } #endif } return(null); }
public void Import_from_UserVoice() { string oauthKey = Environment.GetEnvironmentVariable("USERVOICE_KEY"); //required to get emails const int resultsPerPage = 20; var i = 0; List <object> suggestions = null; var client = new JsonServiceClient("http://localhost:16325") { BearerToken = Environment.GetEnvironmentVariable("TECHSTACKS_DEVELOPMENT_TOKEN") }; do { var url = $"https://servicestack.uservoice.com/api/v1/forums/176786/suggestions.json?per_page={resultsPerPage}&page={++i}&oauth_consumer_key={oauthKey}"; var json = url.GetJsonFromUrl(req => req.AddBearerToken(oauthKey)); var response = (Dictionary <string, object>)JSON.parse(json); suggestions = (List <object>)response["suggestions"]; var userVoiceUsers = new Dictionary <string, UserVoiceUser>(StringComparer.OrdinalIgnoreCase); var techstacksUsers = new Dictionary <string, UserRef>(StringComparer.OrdinalIgnoreCase); UserVoiceUser toUser(object oUser) { if (!(oUser is Dictionary <string, object> user)) { return(null); } if (!user.TryGetValue("email", out var oEmail)) { "EMAIL NOT FOUND:".Print(); user.PrintDump(); return(null); } var email = (string)oEmail; if (!userVoiceUsers.ContainsKey("user")) { return(new UserVoiceUser { Id = (int)user["id"], Name = (string)user["name"], Email = email, AvatarUrl = (string)user["avatar_url"], CreatedAt = user["created_at"].ToString().ConvertTo <DateTime>(), UpdatedAt = user["updated_at"].ToString().ConvertTo <DateTime>(), }); } return(null); } foreach (var oSuggestion in suggestions) { var request = new ImportUserVoiceSuggestion { OrganizationId = 1, }; try { if (oSuggestion is Dictionary <string, object> suggestion) { request.Url = (string)suggestion["url"]; request.Id = (int)suggestion["id"]; request.State = (string)suggestion["state"]; request.Title = (string)suggestion["title"]; //Can be null and just have title request.Text = suggestion["text"] as string; if (request.Text != null) { request.Text = JsonTypeSerializer.Unescape(request.Text); } request.FormattedText = suggestion["formatted_text"] as string; if (request.FormattedText != null) { request.FormattedText = JsonTypeSerializer.Unescape(request.FormattedText); } request.VoteCount = (int)suggestion["vote_count"]; request.CreatedAt = suggestion["created_at"].ToString().ConvertTo <DateTime>(); request.UpdatedAt = suggestion["updated_at"].ToString().ConvertTo <DateTime>(); if (suggestion.TryGetValue("category", out var category)) { request.Category = category as string; } if (suggestion.TryGetValue("topic", out var oTopic) && oTopic is Dictionary <string, object> topic) { request.TopicId = (int)topic["id"]; } if (suggestion.TryGetValue("creator", out var creator)) { request.Creator = toUser(creator); } if (suggestion.TryGetValue("closed_at", out var oClosedAt) && oClosedAt is string closeAt) { request.ClosedAt = oClosedAt.ConvertTo <DateTime>(); } if (suggestion.TryGetValue("status_changed_by", out var statusUser)) { request.StatusChangedBy = toUser(statusUser); } if (suggestion.TryGetValue("status", out var oStatus) && oStatus is Dictionary <string, object> status) { var statusKey = (string)status["key"]; if (statusKey != "published") { request.StatusKey = statusKey; request.StatusHexColor = (string)status["hex_color"]; } } if (suggestion.TryGetValue("response", out var statusResponse) && statusResponse is Dictionary <string, object> oStatusResponse) { request.Response = new UserVoiceComment { Text = (string)oStatusResponse["text"], FormattedText = (string)oStatusResponse["formatted_text"], CreatedAt = oStatusResponse["created_at"].ToString().ConvertTo <DateTime>(), }; if (request.Response.Text != null) { request.Response.Text = JsonTypeSerializer.Unescape(request.Response.Text); } if (request.Response.FormattedText != null) { request.Response.FormattedText = JsonTypeSerializer.Unescape(request.Response.FormattedText); } if (oStatusResponse.TryGetValue("creator", out var responseCreator)) { request.Response.Creator = toUser(responseCreator); } } $"Importing Suggestion {request.Id}: {request.Title}".Print(); var newPost = client.Post(request); $"Imported Post {newPost.PostId}: {newPost.PostSlug}".Print(); } } catch (Exception ex) { $"Could not import suggestion: {ex.Message}\n{ex.StackTrace}".Print(); oSuggestion.PrintDump(); } } } while (suggestions.Count >= resultsPerPage); }