I use `JsonNode` for my dynamic type, it works great for a `kwargs` standin. I 
usually name it `options`, but for sake of consistency I named it `kwargs` 
here. I use it all over an in-production tool at work, with permission to share:
    
    
    import std/json
    import std/strformat
    
    proc get_json_value*[T: bool | float | int | string | JsonNode](node: 
JsonNode,
                                                                    keys: 
seq[string],
                                                                    default: 
T): T =
        var current_node = node
        
        for key in keys:
            if key in current_node:
                current_node = current_node[key]
            else:
                return default
        
        when T is bool:
            if current_node.kind == JBool:
                return current_node.get_bool
        when T is float:
            if current_node.kind == JFloat or current_node.kind == JInt:
                return current_node.get_float
        when T is int:
            if current_node.kind == JInt:
                return current_node.get_int
        when T is string:
            if current_node.kind == JString:
                return current_node.get_str
        when T is JsonNode:
            if current_node.kind in [JObject, JArray]:
                return current_node
        
        return default
    
    proc get_json_value*[T: bool | float | int | string | JsonNode](node: 
JsonNode,
                                                                    key: string,
                                                                    default: 
T): T =
        node.get_json_value(@[key], default)
    
    proc foo(a: int, b: string, kwargs: JsonNode = %*{}) =
        echo &"Calling foo() with {kwargs=}"
        let kwarg1 = kwargs.get_json_value("kwarg1", "default")
        echo &"{kwarg1=}"
    
    foo(1, "bar")
    foo(2, "baz", %*{"kwarg1": "something else"})
    
    
    Run

Output:
    
    
    Calling foo() with kwargs={}
    kwarg1=default
    Calling foo() with kwargs={"kwarg1":"something else"}
    kwarg1=something else
    
    
    Run

Reply via email to