
use type

extend HashMap[K, V] {

    #if is_type_of_class(K, String)
    + fn to_json_value() Value $to {
        let result = Map[Value]{}
        each this as v, k {
            result.set(k, value(v))
        }
        return new_object(result)
    }
    + static fn from_json_value_auto[X](val: X) SELF {
        let result = SELF.new()
        let items = val.map()
        each items as v, k {
            result.set(k, to_type[V](v))
        }
        return result
    }
    #end
}

extend FlatMap[K, V] {

    #if is_type_of_class(K, String)
    + fn to_json_value() Value $to {
        let result = Map[Value]{}
        each this as v, k {
            result.set(k, value(v))
        }
        return new_object(result)
    }
    + static fn from_json_value_auto[X](val: X) SELF {
        let result = SELF.new()
        let items = val.map()
        each items as v, k {
            result.set(k, to_type[V](v))
        }
        return result
    }
    #end
}

extend Array[T] {

    + fn to_json_value() Value $to {
        let result = type:Array[Value].new()
        each this as v {
            result.append(value(v))
        }
        return new_array(result)
    }
    + static fn from_json_value_auto[X](val: X) SELF {
        let result = SELF.new()
        let items = val.array()
        each items as v {
            result.append(to_type[T](v))
        }
        return result
    }
}

extend String {

    + fn to_json_value() Value $to {
        return new_string(this)
    }
    + static fn from_json_value(val: Value) String {
        return val.string()
    }
}