ValveResourceFormat / ValveKeyValue

📃 Next-generation Valve's key value framework for .NET
https://www.nuget.org/packages/ValveKeyValue/
MIT License
148 stars 37 forks source link

Simplify the api #30

Open xPaw opened 3 years ago

xPaw commented 3 years ago

12:21 <@Netshroud> [...] though I do want to revisit vkv because I built a very confusing api the first time around 12:22 <@Netshroud> though C# now has Records and withers so it might be easier

yaakov-h commented 1 year ago

Pain points from related issues:

  1. Adding and removing items from a list (#78). Although I wanted this to be immutable, we can still improve this with "with"ers or with builders (like System.Collections.Immutable) or wither-like helper methods (like Roslyn).
  2. Weakly typed use of the API requires casting to enumerate children (#21), e.g.
    
    var depots = data["Software"]["Valve"]["Steam"]["depots"];

foreach (var depot in (IEnumerable)depots) { Console.WriteLine(depot.Name); }

3. Easy conversion to list. #56 tried this:
```cs
List<KVObject> collection = ((KVCollectionValue)app.Data["config"]["launch"]).children;

which is just awful from a consumer POV, even though it works (with internal access rights).

  1. We're not very Intellisense-friendly, "proper" use relies on knowing that you can cast these objects to their regular runtime type, e.g (int)value.

Feel free to add more.

xPaw commented 1 year ago

I am not sure what we are gaining from having it be immutable.

I'd throw in that null support is needed for KV3

yaakov-h commented 1 year ago

IMO most of the time we're just reading Valve's stuff, so we don't typically need to mutate it.

Though another way of looking at it would be - if you want immutable types, deserialise it to an immutable type. (We might need to add support for records / init properties to make this happen.)

What does null look like in KV3?

yaakov-h commented 1 year ago

Fortunately, records already work. I've added a test for them in ed10cc1.

xPaw commented 1 year ago

so we don't typically need to mutate it.

I do sometimes.

What does null look like in KV3?

Literal null non quoted. I partially support it in my PR by removing the check for non-nullable object value.

xPaw commented 8 months ago

Another annoyance I'm running into: KVObject["str"] returns KVValue, but the underlying type is a private KVObjectValue, so I can't cast the KVValue back into KVObject.

And KVObject doesn't extend KVValue, so this seems very inconsistent. This doesn't matter for this[] accessor as it's implemented on both, but if you want to pass around the objects, this gets messy.

Are consumers only ever expected to cast any value into KVValue, but internally we create KVObjectValue with types?

I've been trying to convert VRF to use VKV's types, and it's very painful.

For reference: https://github.com/ValveResourceFormat/ValveResourceFormat/blob/d4397512003fcf85bd98017ff1649b3e1f7ff948/ValveResourceFormat/Serialization/KeyValues/KVObject.cs

https://github.com/ValveResourceFormat/ValveResourceFormat/blob/d4397512003fcf85bd98017ff1649b3e1f7ff948/ValveResourceFormat/Serialization/KeyValues/KVValue.cs

https://github.com/ValveResourceFormat/ValveResourceFormat/blob/master/ValveResourceFormat/Serialization/IKeyValueCollection.cs