Nett icon indicating copy to clipboard operation
Nett copied to clipboard

Action when Toml.ReadFile<T>(file) is missing keys or has extra keys

Open avsteele opened this issue 5 years ago • 3 comments

I can use Toml.ReadFile<T> to parse a TOML and set some class T's member's from it.

If the TOML file does not have a key corresponding to a member of T, then that member has its default value.

If the TOML file has additional entries beyond those contained in T, those keys are silently ignored by default

I didn't see a way to configure TomlSettings to Throw or specify a Action to take in the above circumstances. Is this possible?

Thanks for Nett!

avsteele avatar Sep 24 '19 18:09 avsteele

For the fist case (file does not have key) there is no built in functionality. I will have to think about if this make sense and can be implemented in a sane way.

The 2nd use case was handled in issue #78

paiden avatar Sep 25 '19 15:09 paiden

Here's an stab at it. It works for the basic tests I've run, including nested/subsections etc...I havnt thought about Toml dicts yet (I've never used them).

The test for whether to go deeper into the object to be filled probably needs some more thought.

static void TomlObjCompare(TomlTable tt, Type t, string path  = "")
{
    PropertyInfo[] properties = t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static);
    if (path != "") path += ".";
    path += t.Name;
    foreach (PropertyInfo property in properties)
    {
        //Console.WriteLine($"{property.PropertyType}\t: {path + "." + property.Name}");
        // This is an attempt to identify a base type
        if (!property.PropertyType.Namespace.StartsWith("System"))
        {
            TomlObjCompare(tt.Get<TomlTable>(property.Name),property.PropertyType, path);
        }
        // test if name is in Tomltable
        if( !tt.ContainsKey(property.Name))
        {
            // Insert 'not found' behavior here... e.g. throw
            Console.WriteLine($"{path+"."+property.Name} not found in TomlTable");
        }
    }
}

Usage

var fname = "config/config1.toml";
var tt = Toml.ReadFile(fname);
Console.WriteLine($"Comparing {a.GetType()} to {fname}\n");
TomlObjCompare(tt, a.GetType());

avsteele avatar Sep 28 '19 21:09 avsteele

This works only for simple cases, as soon as you start to use converters etc. this will not work correctly anymore.

Still thinking about possible solution... unfortunately I have not a lot of time at the moment to work on Nett, so it may take some time until I can give a outlook on what to expect regarding this issue here.

paiden avatar Oct 16 '19 11:10 paiden