mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Begin working on JSON record decoding
And we've hit a borrow panic 😍
This commit is contained in:
parent
0d96f4fc7d
commit
29793fac32
6 changed files with 132 additions and 8 deletions
|
@ -22,6 +22,7 @@ interface Decode
|
|||
bool,
|
||||
string,
|
||||
list,
|
||||
record,
|
||||
custom,
|
||||
decodeWith,
|
||||
fromBytesPartial,
|
||||
|
@ -57,6 +58,7 @@ DecoderFormatting has
|
|||
bool : Decoder Bool fmt | fmt has DecoderFormatting
|
||||
string : Decoder Str fmt | fmt has DecoderFormatting
|
||||
list : Decoder elem fmt -> Decoder (List elem) fmt | fmt has DecoderFormatting
|
||||
record : state, (state, Str -> [Keep (Decoder state fmt), Skip]), (state -> Result val DecodeError) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
|
||||
custom : (List U8, fmt -> DecodeResult val) -> Decoder val fmt | fmt has DecoderFormatting
|
||||
custom = \decode -> @Decoder decode
|
||||
|
|
|
@ -16,6 +16,7 @@ interface Json
|
|||
Decode,
|
||||
Decode.{
|
||||
DecoderFormatting,
|
||||
DecodeResult,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -57,6 +58,7 @@ Json := {} has [
|
|||
bool: decodeBool,
|
||||
string: decodeString,
|
||||
list: decodeList,
|
||||
record: decodeRecord,
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -316,7 +318,8 @@ decodeBool = Decode.custom \bytes, @Json {} ->
|
|||
else
|
||||
{ result: Err TooShort, rest: bytes }
|
||||
|
||||
decodeString = Decode.custom \bytes, @Json {} ->
|
||||
jsonString : List U8 -> DecodeResult Str
|
||||
jsonString = \bytes ->
|
||||
{ before, others: afterStartingQuote } = List.split bytes 1
|
||||
|
||||
if
|
||||
|
@ -335,6 +338,9 @@ decodeString = Decode.custom \bytes, @Json {} ->
|
|||
else
|
||||
{ result: Err TooShort, rest: bytes }
|
||||
|
||||
decodeString = Decode.custom \bytes, @Json {} ->
|
||||
jsonString bytes
|
||||
|
||||
decodeList = \decodeElem -> Decode.custom \bytes, @Json {} ->
|
||||
decodeElems = \chunk, accum ->
|
||||
when Decode.decodeWith chunk decodeElem (@Json {}) is
|
||||
|
@ -372,3 +378,72 @@ decodeList = \decodeElem -> Decode.custom \bytes, @Json {} ->
|
|||
{ result: Err TooShort, rest }
|
||||
else
|
||||
{ result: Err TooShort, rest: bytes }
|
||||
|
||||
parseExactChar : List U8, U8 -> DecodeResult {}
|
||||
parseExactChar = \bytes, char ->
|
||||
when List.get bytes 0 is
|
||||
Ok c ->
|
||||
if
|
||||
c == char
|
||||
then
|
||||
{ result: Ok {}, rest: (List.split bytes 1).others }
|
||||
else
|
||||
{ result: Err TooShort, rest: bytes }
|
||||
|
||||
Err _ -> { result: Err TooShort, rest: bytes }
|
||||
|
||||
openBrace : List U8 -> DecodeResult {}
|
||||
openBrace = \bytes -> parseExactChar bytes (asciiByte '{')
|
||||
|
||||
closingBrace : List U8 -> DecodeResult {}
|
||||
closingBrace = \bytes -> parseExactChar bytes (asciiByte '}')
|
||||
|
||||
recordKey : List U8 -> DecodeResult Str
|
||||
recordKey = \bytes -> jsonString bytes
|
||||
|
||||
anything : List U8 -> DecodeResult {}
|
||||
anything = \bytes -> { result: Err TooShort, rest: bytes }
|
||||
|
||||
colon : List U8 -> DecodeResult {}
|
||||
colon = \bytes -> parseExactChar bytes (asciiByte ':')
|
||||
|
||||
comma : List U8 -> DecodeResult {}
|
||||
comma = \bytes -> parseExactChar bytes (asciiByte ',')
|
||||
|
||||
tryDecode : DecodeResult a, ({ val : a, rest : List U8 } -> DecodeResult b) -> DecodeResult b
|
||||
tryDecode = \{ result, rest }, mapper ->
|
||||
when result is
|
||||
Ok val -> mapper { val, rest }
|
||||
Err e -> { result: Err e, rest }
|
||||
|
||||
decodeRecord = \initialState, stepField, finalizer -> Decode.custom \bytes, @Json {} ->
|
||||
decodeFields : st, List U8 -> DecodeResult st
|
||||
decodeFields = \state, kvBytes ->
|
||||
{ val: key, rest } <- recordKey kvBytes |> tryDecode
|
||||
{ rest: afterColonBytes } <- colon rest |> tryDecode
|
||||
{ val: newState, rest: beforeCommaOrBreak } <- tryDecode
|
||||
(
|
||||
when stepField state key is
|
||||
Skip ->
|
||||
{ rest: beforeCommaOrBreak } <- afterColonBytes |> anything |> tryDecode
|
||||
{ result: Ok state, rest: beforeCommaOrBreak }
|
||||
|
||||
Keep decoder ->
|
||||
Decode.decodeWith afterColonBytes decoder (@Json {})
|
||||
)
|
||||
|
||||
{ result: commaResult, rest: nextBytes } = comma beforeCommaOrBreak
|
||||
|
||||
when commaResult is
|
||||
Ok {} -> decodeFields newState nextBytes
|
||||
Err _ -> { result: Ok newState, rest: nextBytes }
|
||||
|
||||
{ rest: afterBraceBytes } <- bytes |> openBrace |> tryDecode
|
||||
|
||||
{ val: endStateResult, rest: beforeClosingBraceBytes } <- decodeFields initialState afterBraceBytes |> tryDecode
|
||||
|
||||
{ rest: afterRecordBytes } <- beforeClosingBraceBytes |> closingBrace |> tryDecode
|
||||
|
||||
when finalizer endStateResult is
|
||||
Ok val -> { result: Ok val, rest: afterRecordBytes }
|
||||
Err e -> { result: Err e, rest: afterRecordBytes }
|
||||
|
|
|
@ -46,7 +46,7 @@ impl WorldAbilities {
|
|||
.unwrap()
|
||||
.insert(module, (store, exposed_types));
|
||||
|
||||
debug_assert!(old_store.is_none(), "{:?} abilities not new", module);
|
||||
//debug_assert!(old_store.is_none(), "{:?} abilities not new", module);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -441,6 +441,19 @@ fn start_phase<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
let our_exposed_types = state
|
||||
.exposed_types
|
||||
.get(&module_id)
|
||||
.unwrap_or_else(|| internal_error!("Exposed types for {:?} missing", module_id))
|
||||
.clone();
|
||||
|
||||
// Add our abilities to the world.
|
||||
state.world_abilities.insert(
|
||||
module_id,
|
||||
abilities_store.clone(),
|
||||
our_exposed_types.exposed_types_storage_subs,
|
||||
);
|
||||
|
||||
let derived_module = SharedDerivedModule::clone(&state.derived_module);
|
||||
|
||||
BuildTask::BuildPendingSpecializations {
|
||||
|
|
|
@ -1417,10 +1417,11 @@ define_builtins! {
|
|||
19 DECODE_BOOL: "bool"
|
||||
20 DECODE_STRING: "string"
|
||||
21 DECODE_LIST: "list"
|
||||
22 DECODE_CUSTOM: "custom"
|
||||
23 DECODE_DECODE_WITH: "decodeWith"
|
||||
24 DECODE_FROM_BYTES_PARTIAL: "fromBytesPartial"
|
||||
25 DECODE_FROM_BYTES: "fromBytes"
|
||||
22 DECODE_RECORD: "record"
|
||||
23 DECODE_CUSTOM: "custom"
|
||||
24 DECODE_DECODE_WITH: "decodeWith"
|
||||
25 DECODE_FROM_BYTES_PARTIAL: "fromBytesPartial"
|
||||
26 DECODE_FROM_BYTES: "fromBytes"
|
||||
}
|
||||
13 JSON: "Json" => {
|
||||
0 JSON_JSON: "Json"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue