Skip to content

Commit

Permalink
Fix encoder for tuples inside lists
Browse files Browse the repository at this point in the history
  • Loading branch information
GearsDatapacks authored and lpil committed Feb 11, 2025
1 parent 6bf9535 commit 76a0171
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
33 changes: 26 additions & 7 deletions compiler-core/src/language_server/code_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3424,8 +3424,9 @@ impl<'a> EncoderPrinter<'a> {

fn encoder_for(&mut self, encoded_value: &str, type_: &Type, indent: usize) -> EcoString {
let module_name = self.printer.print_module(JSON_MODULE);
let is_capture = encoded_value == "_";
let maybe_capture = |mut function: EcoString| {
if encoded_value == "_" {
if is_capture {
function
} else {
function.push('(');
Expand All @@ -3444,21 +3445,39 @@ impl<'a> EncoderPrinter<'a> {
} else if type_.is_string() {
maybe_capture(eco_format!("{module_name}.string"))
} else if let Some(types) = type_.tuple_types() {
let (tuple, new_indent) = if is_capture {
("value", indent + 4)
} else {
(encoded_value, indent + 2)
};

let encoders = types
.iter()
.enumerate()
.map(|(index, type_)| {
self.encoder_for(&format!("{encoded_value}.{index}"), type_, indent + 2)
self.encoder_for(&format!("{tuple}.{index}"), type_, new_indent)
})
.collect_vec();

eco_format!(
"{module_name}.preprocessed_array([
if is_capture {
eco_format!(
"fn(value) {{
{indent} {module_name}.preprocessed_array([
{indent} {encoders},
{indent} ])
{indent}}}",
indent = " ".repeat(indent),
encoders = encoders.join(&format!(",\n{}", " ".repeat(new_indent))),
)
} else {
eco_format!(
"{module_name}.preprocessed_array([
{indent} {encoders},
{indent}])",
indent = " ".repeat(indent),
encoders = encoders.join(&format!(",\n{}", " ".repeat(indent + 2))),
)
indent = " ".repeat(indent),
encoders = encoders.join(&format!(",\n{}", " ".repeat(new_indent))),
)
}
} else {
let type_information = type_.named_type_information();
let type_information: Option<(&str, &str, &[Arc<Type>])> =
Expand Down
13 changes: 13 additions & 0 deletions compiler-core/src/language_server/tests/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5053,6 +5053,19 @@ fn map(list: List(a), fun: fn(a) -> b) -> List(b) { todo }
);
}

#[test]
fn generate_json_encoder_list_of_tuples() {
assert_code_action!(
GENERATE_JSON_ENCODER,
"
pub type Wibble {
Wibble(values: List(#(Int, String)))
}
",
find_position_of("type").to_selection()
);
}

#[test]
fn no_code_action_to_generate_json_encoder_for_multi_variant_type() {
assert_no_code_actions!(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
source: compiler-core/src/language_server/tests/action.rs
expression: "\npub type Wibble {\n Wibble(values: List(#(Int, String)))\n}\n"
---
----- BEFORE ACTION

pub type Wibble {
Wibble(values: List(#(Int, String)))
}


----- AFTER ACTION
import gleam/json

pub type Wibble {
Wibble(values: List(#(Int, String)))
}

fn encode_wibble(wibble: Wibble) -> json.Json {
json.object([
#("values", json.array(wibble.values, fn(value) {
json.preprocessed_array([
json.int(value.0),
json.string(value.1),
])
})),
])
}

0 comments on commit 76a0171

Please sign in to comment.