dezhidki / Tommy

A single-file TOML reader and writer for C#
MIT License
212 stars 16 forks source link

How to handle TomlLazy? #44

Open leftbones opened 7 months ago

leftbones commented 7 months ago

From the README and the code I can't quite surmise what TomlLazy is actually used for, but in my tests it seems that if I try to access a key that doesn't exist in a table, a TomlLazy is returned instead. Is there a way I can check if a key doesn't exist so I can handle that?

leftbones commented 7 months ago

Right after posting this, I found that I could check with Table["Key"].IsTable and that would return true only if the key exists, which does solve my problem. I am still curious what the use case for TomlLazy is, however.

dezhidki commented 7 months ago

Hi, thanks for the question! Glad you managed to find the solution to your question.

TomlLazy is mainly an abstraction over an array or a table that can be automatically created on access. The basic use case is to allow composing TOML files implicitly as such:

var toml = new TomlTable();
toml["array"][0] = "val1";  // toml["array"] returns a TomlLazy instance, but index access [0] automatically replaces TomlLazy with TomlArray
toml["array"][1] = "val2"; // toml["array"] now returns a TomlArray

The basic case is not really interesting, but the TomlLazy becomes useful when you use property initializiers, allowing you to construct the entire table in JSON-like syntax:

var toml = new TomlTable
{
  ["owner"] =                // Here TomlLazy is implicitly created 
  {
     ["name"] = "Foo",   // Here, TomlLazy is implicitly replaced with a TomlTable
     ["dob"]  = "bar",
  },
  ["array"] = { [0] = 1, [1] = 2 }  // Same thing, but now TomlArray is created because of index access
};

This pattern was originally taken from SimpleJSON which at some point was a fairly popular JSON parser/writer for Unity games back when C# did not have.

Nowadays, I'd say that this implicit behaviour is somewhat cryptic, and it belongs to a separate library. Alas, I think it's a breaking change to remove it.

PS: TomlNode has a HasKey method to check whether it contains a key of certain name. If I understood your usecase correctly, Table.HasKey("Key") should do the trick.