Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/library/Telegram.BotAPI/Converters/RichTextConverter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) 2026 Quetzal Rivera.
// Licensed under the MIT License, See LICENCE in the project root for license information.

using System.Text.Json;
using Telegram.BotAPI.RichMessages;

namespace Telegram.BotAPI.Converters;
Expand All @@ -12,4 +13,41 @@ public sealed class RichTextConverter : DiscriminatorJsonConverter<RichText>
{
/// <inheritdoc />
public override string PropertyName => PropertyNames.Type;

/// <inheritdoc/>
public override RichText? Read(
ref Utf8JsonReader reader,
Type typeToConvert,
JsonSerializerOptions options
)
{
return reader.TokenType switch
{
JsonTokenType.StartArray => new RichTextArray(
JsonSerializer.Deserialize<RichText[]>(ref reader, options)!
),
JsonTokenType.String => new RichTextPlainText(reader.GetString()!),
JsonTokenType.StartObject => base.Read(ref reader, typeToConvert, options),
_ => throw new JsonException(
$"Failed to deserialize RichText. Unexpected token {reader.TokenType}"
),
};
}

/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, RichText value, JsonSerializerOptions options)
{
if (value is RichTextArray array)
{
JsonSerializer.Serialize(writer, (IEnumerable<RichText>)array, options);
}
else if (value is RichTextPlainText plainText)
{
JsonSerializer.Serialize(writer, (string)plainText, options);
}
else
{
base.Write(writer, value, options);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace Telegram.BotAPI.RichMessages;
/// </list>
/// </summary>
[JsonConverter(typeof(RichTextConverter))]
public abstract class RichText
public abstract partial class RichText
{
/// <summary>
/// Type of the rich text
Expand Down
32 changes: 32 additions & 0 deletions src/library/Telegram.BotAPI/RichMessages/RichText/RichTextArray.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Collections;
using Telegram.BotAPI.Converters;

namespace Telegram.BotAPI.RichMessages;

/// <summary>
/// Represents an array of <see cref="RichText"/>.
/// </summary>
[JsonConverter(typeof(RichTextConverter))]
public class RichTextArray(IEnumerable<RichText> items) : RichText, IEnumerable<RichText>
{
/// <summary>
/// Type of the rich text
/// </summary>
public override string Type => "RichTextArray";

private readonly IEnumerable<RichText> items = items;

/// <inheritdoc/>
public IEnumerator<RichText> GetEnumerator() => this.items.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

public partial class RichText
{
#pragma warning disable IDE0023 // Use block body for conversion operator
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
public static implicit operator RichText(RichText[] value) => new RichTextArray(value);
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
#pragma warning restore IDE0023 // Use block body for conversion operator
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Diagnostics;
using Telegram.BotAPI.Converters;

namespace Telegram.BotAPI.RichMessages;

/// <summary>
/// Plain text
/// </summary>
[JsonConverter(typeof(RichTextConverter))]
[DebuggerDisplay("{value}")]
public class RichTextPlainText(string plainText) : RichText
{
/// <summary>
/// Type of the rich text
/// </summary>
public override string Type => "RichTextPlainText";

private readonly string value = plainText;

/// <inheritdoc/>
public override string ToString() => this.value;

#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
#pragma warning disable IDE0023 // Use block body for conversion operator
public static implicit operator RichTextPlainText(string value) => new(value);

public static implicit operator string(RichTextPlainText instance) => instance.value;
}

public partial class RichText
{
public static implicit operator RichText(string value) => new RichTextPlainText(value);
}

#pragma warning restore IDE0023 // Use block body for conversion operator
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
5 changes: 3 additions & 2 deletions src/library/Telegram.BotAPI/Telegram.BotAPI.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Version>10.3.0</Version>
<Version>10.3.1</Version>
<PackageId>$(AssemblyName)</PackageId>
<Authors>Quetzal Rivera</Authors>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Expand All @@ -25,7 +25,8 @@
<PackageProjectUrl>https://github.com/Eptagone/Telegram.BotAPI</PackageProjectUrl>
<RepositoryType></RepositoryType>
<AssemblyName>Telegram.BotAPI</AssemblyName>
<PackageReleaseNotes>Updated to Bot API v10.3</PackageReleaseNotes>
<PackageReleaseNotes>Fix serialization/deserialization of RichText types when the value is a
plain text or an array of RichText instances</PackageReleaseNotes>
<EnableNETAnalyzers>true</EnableNETAnalyzers>
<AnalysisLevel>latest-recommended</AnalysisLevel>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down
12 changes: 12 additions & 0 deletions src/tests/Telegram.BotAPI.Tests/Serialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Telegram.BotAPI.InlineMode;
using Telegram.BotAPI.RichMessages;
using Telegram.BotAPI.UpdatingMessages;

namespace Telegram.BotAPI.Tests;
Expand Down Expand Up @@ -97,4 +98,15 @@ [new InlineKeyboardButton("Button") { CallbackData = "data" }],
).MessageText
);
}

[Fact]
public void DeserializeRichText()
{
var json =
"""[{"type":"bold","text":"hi"},{"type":"italic","text":["a",{"type":"bold","text":"b"}]}]""";
var instances = JsonSerializer.Deserialize<RichText[]>(json);
var serializedInstances = JsonSerializer.Serialize(instances);

Assert.Equal(json, serializedInstances);
}
}
Loading