aaubry / YamlDotNet

YamlDotNet is a .NET library for YAML
MIT License
2.48k stars 466 forks source link

is it possible to style a string in a special way? #916

Closed modern-nm closed 3 months ago

modern-nm commented 3 months ago

Hi, i trying to write some logs. All logs written by other soft and have structure like: Entries:

It deserializes to my objects correct. But i have a problem with writing log back to file. Structure of file written by me looks like:

Entries:

It's unreadable. Can i make yamldotnet serializer to write yaml string like first example?

EdwardCooke commented 3 months ago

I think the closest you could get right now is serialize as json. It would wrap everything in quotes though. However most log aggregators can easily read json.

EdwardCooke commented 3 months ago

I just figured this out for you, using a custom event emitter you can set the style of the mapping to flow.

using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.EventEmitters;

var serializer = new SerializerBuilder()
    .WithEventEmitter(inner => new MappingNodeEventEmitter(inner), where => where.OnBottom())
    .Build();

var test = new Log
{
    Author = "test",
    Changes = new[] {
        new Change{
            Message = "Test1",
            Type = "Tweak"
        },
        new Change{
            Message = "Test2",
            Type = "Tweak"
        }
    }
};

var serialized = serializer.Serialize(test);
Console.WriteLine(serialized);

class MappingNodeEventEmitter : ChainedEventEmitter
{
    public MappingNodeEventEmitter(IEventEmitter nextEmitter) : base(nextEmitter)
    {
    }

    public override void Emit(MappingStartEventInfo eventInfo, IEmitter emitter)
    {
        if (eventInfo.Source.StaticType == typeof(Change))
        {
            eventInfo.Style = MappingStyle.Flow;
        }
        base.Emit(eventInfo, emitter);
    }
}

class Log
{
    public string Author { get; set; }
    public Change[] Changes { get; set; }
}
class Change
{
    public string Message { get; set; }
    public string Type { get; set; }
}

Results in

Author: test
Changes:
- {Message: Test1, Type: Tweak}
- {Message: Test2, Type: Tweak}
modern-nm commented 3 months ago

This is just what i needed. I already got on the trail of EventEmitter, but I still didn't understand how I could achieve such a result until you showed up. I really appreciate your help, @EdwardCooke .