mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-24 06:55:15 +00:00
Add deriving toEncoder for opaques
This commit is contained in:
parent
83813afeaf
commit
c4f9aa6fe6
3 changed files with 82 additions and 7 deletions
|
@ -639,6 +639,45 @@ fn separate_implemented_and_required_members(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn synthesize_derived_to_encoder<'a>(
|
||||||
|
env: &mut Env<'a>,
|
||||||
|
at_opaque: &'a str,
|
||||||
|
region: Region,
|
||||||
|
) -> ast::Expr<'a> {
|
||||||
|
let alloc_pat = |it| env.arena.alloc(Loc::at(region, it));
|
||||||
|
let alloc_expr = |it| env.arena.alloc(Loc::at(region, it));
|
||||||
|
|
||||||
|
let payload = env.arena.alloc_str("#payload");
|
||||||
|
|
||||||
|
// \@Opaq payload
|
||||||
|
let opaque_ref = alloc_pat(ast::Pattern::OpaqueRef(at_opaque));
|
||||||
|
let opaque_apply_pattern = ast::Pattern::Apply(
|
||||||
|
opaque_ref,
|
||||||
|
&*env
|
||||||
|
.arena
|
||||||
|
.alloc([Loc::at(region, ast::Pattern::Identifier(payload))]),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Encode.toEncoder payload
|
||||||
|
let call_member = alloc_expr(ast::Expr::Apply(
|
||||||
|
alloc_expr(ast::Expr::Var {
|
||||||
|
module_name: "Encode",
|
||||||
|
ident: "toEncoder",
|
||||||
|
}),
|
||||||
|
&*env.arena.alloc([&*alloc_expr(ast::Expr::Var {
|
||||||
|
module_name: "",
|
||||||
|
ident: payload,
|
||||||
|
})]),
|
||||||
|
roc_module::called_via::CalledVia::Space,
|
||||||
|
));
|
||||||
|
|
||||||
|
// \@Opaq payload -> Encode.toEncoder payload
|
||||||
|
ast::Expr::Closure(
|
||||||
|
env.arena.alloc([Loc::at(region, opaque_apply_pattern)]),
|
||||||
|
call_member,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn synthesize_derived_hash<'a>(
|
fn synthesize_derived_hash<'a>(
|
||||||
env: &mut Env<'a>,
|
env: &mut Env<'a>,
|
||||||
at_opaque: &'a str,
|
at_opaque: &'a str,
|
||||||
|
@ -756,14 +795,9 @@ fn synthesize_derived_member_impl<'a>(
|
||||||
let (impl_name, def_body): (String, ast::Expr<'a>) = match ability_member {
|
let (impl_name, def_body): (String, ast::Expr<'a>) = match ability_member {
|
||||||
Symbol::ENCODE_TO_ENCODER => (
|
Symbol::ENCODE_TO_ENCODER => (
|
||||||
format!("#{}_toEncoder", opaque_name),
|
format!("#{}_toEncoder", opaque_name),
|
||||||
todo!(),
|
synthesize_derived_to_encoder(env, at_opaque, region),
|
||||||
//synthesize_derived_to_encoder(env, scope, at_opaque, region),
|
|
||||||
),
|
|
||||||
Symbol::DECODE_DECODER => (
|
|
||||||
format!("#{}_decoder", opaque_name),
|
|
||||||
todo!(),
|
|
||||||
//synthesize_derived_decoder(env, scope, at_opaque, region),
|
|
||||||
),
|
),
|
||||||
|
Symbol::DECODE_DECODER => (format!("#{}_decoder", opaque_name), todo!()),
|
||||||
Symbol::HASH_HASH => (
|
Symbol::HASH_HASH => (
|
||||||
format!("#{}_hash", opaque_name),
|
format!("#{}_hash", opaque_name),
|
||||||
synthesize_derived_hash(env, at_opaque, region),
|
synthesize_derived_hash(env, at_opaque, region),
|
||||||
|
|
|
@ -8045,6 +8045,23 @@ mod solve_expr {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn derive_to_encoder_for_opaque() {
|
||||||
|
infer_queries!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test" provides [main] to "./platform"
|
||||||
|
|
||||||
|
N := U8 has [Encoding]
|
||||||
|
|
||||||
|
main = Encode.toEncoder (@N 15)
|
||||||
|
# ^^^^^^^^^^^^^^^^
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
@"N#Encode.toEncoder(3) : N -[[#N_toEncoder(3)]]-> Encoder fmt | fmt has EncoderFormatting"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn derive_hash_for_opaque() {
|
fn derive_hash_for_opaque() {
|
||||||
infer_queries!(
|
infer_queries!(
|
||||||
|
|
|
@ -374,6 +374,30 @@ fn encode_use_stdlib_without_wrapping_custom() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
|
fn encode_derive_to_encoder_for_opaque() {
|
||||||
|
assert_evals_to!(
|
||||||
|
indoc!(
|
||||||
|
r#"
|
||||||
|
app "test"
|
||||||
|
imports [Json]
|
||||||
|
provides [main] to "./platform"
|
||||||
|
|
||||||
|
HelloWorld := { a: Str } has [Encoding]
|
||||||
|
|
||||||
|
main =
|
||||||
|
result = Str.fromUtf8 (Encode.toBytes (@HelloWorld { a: "Hello, World!" }) Json.toUtf8)
|
||||||
|
when result is
|
||||||
|
Ok s -> s
|
||||||
|
_ -> "<bad>"
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
RocStr::from(r#"{"a":"Hello, World!"}"#),
|
||||||
|
RocStr
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
|
||||||
fn to_encoder_encode_custom_has_capture() {
|
fn to_encoder_encode_custom_has_capture() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue