using System.Text.Json;
namespace AIStudio.Chat;
///
/// Structured data which a renderer may use instead of the canonical text of a message.
///
///
/// The text stays canonical: providers, copying, exporting, and every renderer which does not know
/// the presentation use it. ContentPresentationView shows the presentation instead, and falls back to
/// the text when its data cannot be read, e.g., from a chat file which was changed by hand.
///
public sealed class ContentPresentation
{
private JsonElement? data;
private int? dataHashCode;
///
/// The renderer which understands the data.
///
public ContentPresentationKind Kind { get; set; } = ContentPresentationKind.NONE;
///
/// The renderer-specific data.
///
public JsonElement? Data
{
get => this.data;
set
{
this.data = value;
this.dataHashCode = null;
}
}
internal static ContentPresentation Create(ContentPresentationKind kind, T data) => new()
{
Kind = kind,
Data = JsonSerializer.SerializeToElement(data),
};
internal ContentPresentation DeepClone() => new()
{
Kind = this.Kind,
Data = this.Data?.Clone(),
};
///
/// A hash code of the data, for telling whether it changed.
///
///
/// Computed once per data, since every render of a message asks for it and computing means
/// writing out the whole data.
///
internal int GetDataHashCode() => this.dataHashCode ??= this.Data is not { ValueKind: not JsonValueKind.Undefined } value
? 0
: value.GetRawText().GetHashCode(StringComparison.Ordinal);
}