Skip to content

Commit

Permalink
feat: implement .toSlice() struct method (#630)
Browse files Browse the repository at this point in the history
  • Loading branch information
Gusarich authored Aug 23, 2024
1 parent 9e5d138 commit bd84017
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- The `exists` method for the `Map` type: PR [#581](https://github.com/tact-lang/tact/pull/581)
- The `storeBit` method for `Builder` type and the `loadBit` method for `Slice` type: PR [#699](https://github.com/tact-lang/tact/pull/699)
- The `toSlice` method for structs and messages: PR [#630](https://github.com/tact-lang/tact/pull/630)

### Changed

Expand Down
51 changes: 48 additions & 3 deletions src/abi/struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ export const StructFunctions: Map<string, AbiFunction> = new Map([
const arg = args[0]!;
if (arg.kind !== "ref") {
throwCompilationError(
"toCell() is implemented only a struct type",
`toCell() is not implemented for type '${arg.kind}'`,
ref,
);
}
const tp = getType(ctx, arg.name);
if (tp.kind !== "struct") {
throwCompilationError(
"toCell() is implemented only a struct type",
`toCell() is not implemented for type '${arg.kind}'`,
ref,
);
}
Expand All @@ -36,7 +36,7 @@ export const StructFunctions: Map<string, AbiFunction> = new Map([
const arg = args[0]!;
if (arg.kind !== "ref") {
throwCompilationError(
"toCell() is implemented only a struct type",
`toCell() is not implemented for type '${arg.kind}'`,
ref,
);
}
Expand Down Expand Up @@ -103,6 +103,51 @@ export const StructFunctions: Map<string, AbiFunction> = new Map([
},
},
],
[
"toSlice",
{
name: "toSlice",
resolve: (ctx, args, ref) => {
if (args.length !== 1) {
throwCompilationError(
"toSlice() expects no arguments",
ref,
);
}
const arg = args[0]!;
if (arg.kind !== "ref") {
throwCompilationError(
`toSlice() is not implemented for type '${arg.kind}'`,
ref,
);
}
const tp = getType(ctx, arg.name);
if (tp.kind !== "struct") {
throwCompilationError(
`toSlice() is not implemented for type '${arg.kind}'`,
ref,
);
}
return { kind: "ref", name: "Slice", optional: false };
},
generate: (ctx, args, resolved, ref) => {
if (resolved.length !== 1) {
throwCompilationError(
"toSlice() expects no arguments",
ref,
);
}
const arg = args[0]!;
if (arg.kind !== "ref") {
throwCompilationError(
`toSlice() is not implemented for type '${arg.kind}'`,
ref,
);
}
return `${ops.writerCell(arg.name, ctx)}(${resolved.map((v) => writeExpression(v, ctx)).join(", ")}).begin_parse()`;
},
},
],
[
"fromSlice",
{
Expand Down
6 changes: 3 additions & 3 deletions src/test/e2e-emulated/__snapshots__/structs.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ exports[`structs should implement structs correctly 13`] = `
"events": [
{
"$type": "storage-charged",
"amount": "0.000000034",
"amount": "0.000000035",
},
{
"$type": "received",
Expand All @@ -300,7 +300,7 @@ exports[`structs should implement structs correctly 13`] = `
},
"bounce": true,
"from": "@treasure(treasure)",
"to": "kQA1LDdzadkUsxlM6-EvD2rMZ2-HuudKWuU-umho_Zw4Aoau",
"to": "kQCHYvnW92OPDk0lG_YI0DX9anWqZygSM4vJtR-ctm9picG2",
"type": "internal",
"value": "10",
},
Expand All @@ -318,7 +318,7 @@ exports[`structs should implement structs correctly 13`] = `
"type": "cell",
},
"bounce": false,
"from": "kQA1LDdzadkUsxlM6-EvD2rMZ2-HuudKWuU-umho_Zw4Aoau",
"from": "kQCHYvnW92OPDk0lG_YI0DX9anWqZygSM4vJtR-ctm9picG2",
"to": "@treasure(treasure)",
"type": "internal",
"value": "9.988015",
Expand Down
6 changes: 5 additions & 1 deletion src/test/e2e-emulated/contracts/structs.tact
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,14 @@ contract StructsTester {
self.t1.s.a == self.t2.s.a && self.t1.s.b == self.t2.s.b;
}

get fun toCell1(s: MyStruct1): Cell {
get fun toCell1(s: MyStruct1): Cell {
return s.toCell();
}

get fun toSlice1(s: MyStruct1): Slice {
return s.toSlice();
}

get fun fromCell1(src: Cell): MyStruct1 {
let s = MyStruct1.fromCell(src);
return s;
Expand Down
4 changes: 4 additions & 0 deletions src/test/e2e-emulated/structs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ describe("structs", () => {
c6.toString(),
);

expect((await contract.getToSlice1(s1)).toString()).toEqual(
c1.toString(),
);

expect(await contract.getFromCell1(c1)).toMatchObject<MyStruct1>(s1);
expect(await contract.getFromCell1(c2)).toMatchObject<MyStruct1>(s2);
expect(await contract.getFromCell2(c3)).toMatchSnapshot();
Expand Down

0 comments on commit bd84017

Please sign in to comment.