146 lines
5.1 KiB
Text
146 lines
5.1 KiB
Text
|
{-|
|
||
|
This utility omits all `null` record fields, which is often the idiomatic way
|
||
|
for a configuration to encode absent fields
|
||
|
-}
|
||
|
let JSON =
|
||
|
missing
|
||
|
sha256:5dc1135d5481cfd6fde625aaed9fcbdb7aa7c14f2e76726aa5fdef028a5c10f5
|
||
|
? ./core.dhall
|
||
|
|
||
|
let List/concatMap =
|
||
|
missing
|
||
|
sha256:3b2167061d11fda1e4f6de0522cbe83e0d5ac4ef5ddf6bb0b2064470c5d3fb64
|
||
|
? ../List/concatMap.dhall
|
||
|
|
||
|
let List/map =
|
||
|
missing
|
||
|
sha256:dd845ffb4568d40327f2a817eb42d1c6138b929ca758d50bc33112ef3c885680
|
||
|
? ../List/map.dhall
|
||
|
|
||
|
let omitNullFields
|
||
|
: JSON.Type → JSON.Type
|
||
|
= λ(old : JSON.Type) →
|
||
|
λ(JSON : Type) →
|
||
|
λ ( json
|
||
|
: { array : List JSON → JSON
|
||
|
, bool : Bool → JSON
|
||
|
, double : Double → JSON
|
||
|
, integer : Integer → JSON
|
||
|
, null : JSON
|
||
|
, object : List { mapKey : Text, mapValue : JSON } → JSON
|
||
|
, string : Text → JSON
|
||
|
}
|
||
|
) →
|
||
|
let result =
|
||
|
old
|
||
|
{ value : JSON, isNull : Bool }
|
||
|
{ string =
|
||
|
λ(x : Text) → { value = json.string x, isNull = False }
|
||
|
, double =
|
||
|
λ(x : Double) → { value = json.double x, isNull = False }
|
||
|
, integer =
|
||
|
λ(x : Integer) → { value = json.integer x, isNull = False }
|
||
|
, object =
|
||
|
λ ( keyValues
|
||
|
: List
|
||
|
{ mapKey : Text
|
||
|
, mapValue : { value : JSON, isNull : Bool }
|
||
|
}
|
||
|
) →
|
||
|
let value =
|
||
|
json.object
|
||
|
( List/concatMap
|
||
|
{ mapKey : Text
|
||
|
, mapValue : { value : JSON, isNull : Bool }
|
||
|
}
|
||
|
{ mapKey : Text, mapValue : JSON }
|
||
|
( λ ( keyValue
|
||
|
: { mapKey : Text
|
||
|
, mapValue :
|
||
|
{ value : JSON, isNull : Bool }
|
||
|
}
|
||
|
) →
|
||
|
if keyValue.mapValue.isNull
|
||
|
then [] : List
|
||
|
{ mapKey : Text
|
||
|
, mapValue : JSON
|
||
|
}
|
||
|
else [ keyValue.{ mapKey }
|
||
|
∧ { mapValue =
|
||
|
keyValue.mapValue.value
|
||
|
}
|
||
|
]
|
||
|
)
|
||
|
keyValues
|
||
|
)
|
||
|
|
||
|
in { value, isNull = False }
|
||
|
, array =
|
||
|
λ(xs : List { value : JSON, isNull : Bool }) →
|
||
|
let value =
|
||
|
json.array
|
||
|
( List/map
|
||
|
{ value : JSON, isNull : Bool }
|
||
|
JSON
|
||
|
( λ(x : { value : JSON, isNull : Bool }) →
|
||
|
x.value
|
||
|
)
|
||
|
xs
|
||
|
)
|
||
|
|
||
|
in { value, isNull = False }
|
||
|
, bool = λ(x : Bool) → { value = json.bool x, isNull = False }
|
||
|
, null = { value = json.null, isNull = True }
|
||
|
}
|
||
|
|
||
|
in result.value
|
||
|
|
||
|
let property =
|
||
|
λ(a : Text) →
|
||
|
λ(b : Double) →
|
||
|
λ(c : Bool) →
|
||
|
assert
|
||
|
: omitNullFields
|
||
|
( JSON.object
|
||
|
( toMap
|
||
|
{ string = JSON.string a
|
||
|
, double = JSON.double b
|
||
|
, bool = JSON.bool c
|
||
|
, null = JSON.null
|
||
|
}
|
||
|
)
|
||
|
)
|
||
|
≡ JSON.object
|
||
|
( toMap
|
||
|
{ string = JSON.string a
|
||
|
, double = JSON.double b
|
||
|
, bool = JSON.bool c
|
||
|
}
|
||
|
)
|
||
|
|
||
|
let example =
|
||
|
assert
|
||
|
: omitNullFields
|
||
|
( JSON.object
|
||
|
( toMap
|
||
|
{ array =
|
||
|
JSON.array [ JSON.object (toMap { null = JSON.null }) ]
|
||
|
}
|
||
|
)
|
||
|
)
|
||
|
≡ JSON.object
|
||
|
( toMap
|
||
|
{ array =
|
||
|
JSON.array
|
||
|
[ JSON.object
|
||
|
([] : List { mapKey : Text, mapValue : JSON.Type })
|
||
|
]
|
||
|
}
|
||
|
)
|
||
|
|
||
|
let example =
|
||
|
assert
|
||
|
: omitNullFields (JSON.array [ JSON.null ]) ≡ JSON.array [ JSON.null ]
|
||
|
|
||
|
in omitNullFields
|