Skip to content

Commit

Permalink
feat: add typegen and docs for RawSlice, Bytes, and StdString (#1342)
Browse files Browse the repository at this point in the history
* ignore

* update test

* adjust supportedTypes

* add projects

* add projects

* add to index

* adjust index

* add sway

* add bytes examples

* add example for raw slice

* add example

* update full

* basics

* adjust fixture hbs

* add tests

* rename

* update docs

* cs

* fmt

* fix names

* adjust
  • Loading branch information
Cameron Manavian authored Oct 13, 2023
1 parent b143f61 commit f6fb12b
Show file tree
Hide file tree
Showing 36 changed files with 514 additions and 2 deletions.
7 changes: 7 additions & 0 deletions .changeset/curvy-houses-roll.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"docs": patch
"@fuel-ts/docs-snippets": patch
"@fuel-ts/abi-typegen": patch
---

Add typegen support and docs for new types
3 changes: 3 additions & 0 deletions apps/docs-snippets/projects/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,7 @@ members = [
"whitelisted-address-predicate",
"echo-evm-address",
"script-transfer-to-contract",
"echo-bytes",
"echo-raw-slice",
"echo-std-string",
]
7 changes: 7 additions & 0 deletions apps/docs-snippets/projects/echo-bytes/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
authors = ["FuelLabs"]
entry = "main.sw"
license = "Apache-2.0"
name = "echo-bytes"

[dependencies]
26 changes: 26 additions & 0 deletions apps/docs-snippets/projects/echo-bytes/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// #region bytes-1
contract;

use std::bytes::Bytes;

abi BytesTest {
fn echo_bytes(value: Bytes) -> Bytes;
fn bytes_comparison(value: Bytes) -> bool;
}

impl BytesTest for Contract {
fn echo_bytes(value: Bytes) -> Bytes {
value
}

fn bytes_comparison(value: Bytes) -> bool {
let mut bytes = Bytes::new();

bytes.push(40u8);
bytes.push(41u8);
bytes.push(42u8);

value == bytes
}
}
// #endregion bytes-1
7 changes: 7 additions & 0 deletions apps/docs-snippets/projects/echo-raw-slice/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
authors = ["FuelLabs"]
entry = "main.sw"
license = "Apache-2.0"
name = "echo-raw-slice"

[dependencies]
20 changes: 20 additions & 0 deletions apps/docs-snippets/projects/echo-raw-slice/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// #region raw-slice-1
contract;

abi RawSliceTest {
fn echo_raw_slice(value: raw_slice) -> raw_slice;
fn raw_slice_comparison(value: raw_slice) -> bool;
}

impl RawSliceTest for Contract {
fn echo_raw_slice(value: raw_slice) -> raw_slice {
value
}

fn raw_slice_comparison(value: raw_slice) -> bool {
let vec: Vec<u64> = Vec::from(value);

vec.len() == 3 && vec.get(0).unwrap() == 40 && vec.get(1).unwrap() == 41 && vec.get(2).unwrap() == 42
}
}
// #endregion raw-slice-1
7 changes: 7 additions & 0 deletions apps/docs-snippets/projects/echo-std-string/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
authors = ["FuelLabs"]
entry = "main.sw"
license = "Apache-2.0"
name = "echo-std-string"

[dependencies]
22 changes: 22 additions & 0 deletions apps/docs-snippets/projects/echo-std-string/src/main.sw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// #region std-string-1
contract;

use std::string::String;

abi StdStringTest {
fn echo_string(value: String) -> String;
fn string_comparison(value: String) -> bool;
}

impl StdStringTest for Contract {
fn echo_string(value: String) -> String {
value
}

fn string_comparison(value: String) -> bool {
let expected = String::from_ascii_str("Hello World");

value.as_bytes() == expected.as_bytes()
}
}
// #endregion std-string-1
3 changes: 3 additions & 0 deletions apps/docs-snippets/projects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export enum SnippetProjectEnum {
ECHO_EMPLOYEE_DATA_VECTOR = 'echo-employee-data-vector',
WHITELISTED_ADDRESS_PREDICATE = 'whitelisted-address-predicate',
ECHO_EVM_ADDRESS = 'echo-evm-address',
ECHO_BYTES = 'echo-bytes',
ECHO_RAW_SLICE = 'echo-raw-slice',
ECHO_STD_STRING = 'echo-std-string',
SCRIPT_TRANSFER_TO_CONTRACT = 'script-transfer-to-contract',
}

Expand Down
34 changes: 34 additions & 0 deletions apps/docs-snippets/src/guide/types/bytes.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Contract } from 'fuels';

import { SnippetProjectEnum } from '../../../projects';
import { createAndDeployContractFromProject } from '../../utils';

describe('Bytes', () => {
let contract: Contract;

beforeAll(async () => {
contract = await createAndDeployContractFromProject(SnippetProjectEnum.ECHO_BYTES);
});

it('should pass bytes to a contract', async () => {
// #region bytes-1

const bytes = [40, 41, 42];

const { value } = await contract.functions.bytes_comparison(bytes).simulate();

expect(value).toBeTruthy();
// #endregion bytes-1
});

it('should retrieve bytes from a contract', async () => {
// #region bytes-2

const bytes = [8, 42, 77];

const { value } = await contract.functions.echo_bytes(bytes).simulate();

expect(value).toStrictEqual(new Uint8Array(bytes));
// #endregion bytes-2
});
});
34 changes: 34 additions & 0 deletions apps/docs-snippets/src/guide/types/raw-slice.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Contract, BN } from 'fuels';

import { SnippetProjectEnum } from '../../../projects';
import { createAndDeployContractFromProject } from '../../utils';

describe('RawSlice', () => {
let contract: Contract;

beforeAll(async () => {
contract = await createAndDeployContractFromProject(SnippetProjectEnum.ECHO_RAW_SLICE);
});

it('should pass a raw slice to a contract', async () => {
// #region raw-slice-1

const rawSlice = [40, 41, 42];

const { value } = await contract.functions.raw_slice_comparison(rawSlice).simulate();

expect(value).toBeTruthy();
// #endregion raw-slice-1
});

it('should retrieve a raw slice from a contract', async () => {
// #region raw-slice-2

const rawSlice = [8, 42, 77];

const { value } = await contract.functions.echo_raw_slice(rawSlice).simulate();

expect(value.map((v: BN) => v.toNumber())).toStrictEqual(rawSlice);
// #endregion raw-slice-2
});
});
34 changes: 34 additions & 0 deletions apps/docs-snippets/src/guide/types/std-string.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Contract } from 'fuels';

import { SnippetProjectEnum } from '../../../projects';
import { createAndDeployContractFromProject } from '../../utils';

describe('StdString', () => {
let contract: Contract;

beforeAll(async () => {
contract = await createAndDeployContractFromProject(SnippetProjectEnum.ECHO_STD_STRING);
});

it('should pass a std string to a contract', async () => {
// #region std-string-1

const stdString = 'Hello World';

const { value } = await contract.functions.string_comparison(stdString).simulate();

expect(value).toBeTruthy();
// #endregion std-string-1
});

it('should retrieve a std string from a contract', async () => {
// #region std-string-2

const stdString = 'Hello Fuel';

const { value } = await contract.functions.echo_string(stdString).simulate();

expect(value).toEqual(stdString);
// #endregion std-string-2
});
});
12 changes: 12 additions & 0 deletions apps/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ export default defineConfig({
text: 'Bits512',
link: '/guide/types/bits512',
},
{
text: 'Bytes',
link: '/guide/types/bytes',
},
{
text: 'Bytes32',
link: '/guide/types/bytes32',
Expand All @@ -96,6 +100,10 @@ export default defineConfig({
text: 'String',
link: '/guide/types/string',
},
{
text: 'Std String',
link: '/guide/types/std-string',
},
{
text: 'Enums',
link: '/guide/types/enums',
Expand All @@ -108,6 +116,10 @@ export default defineConfig({
text: 'Tuples',
link: '/guide/types/tuples',
},
{
text: 'Raw Slice',
link: '/guide/types/raw-slice',
},
{
text: 'Structs',
link: '/guide/types/structs',
Expand Down
14 changes: 14 additions & 0 deletions apps/docs/src/guide/types/bytes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Bytes

A dynamic array of byte values can be represented using the `Bytes` type, which represents raw bytes.

<<< @/../../docs-snippets/src/guide/types/bytes.test.ts#bytes-1{ts:line-numbers}

## Using Bytes

The `Bytes` type can be integrated with your contract calls. Consider the following contract that can compare and return a `Bytes`:

<<< @/../../docs-snippets/projects/echo-bytes/src/main.sw#bytes-1{ts:line-numbers}

A `Bytes` array can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:
<<< @/../../docs-snippets/src/guide/types/bytes.test.ts#bytes-2{ts:line-numbers}
14 changes: 14 additions & 0 deletions apps/docs/src/guide/types/raw-slice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RawSlice

A dynamic array of values can be represented using the `RawSlice` type. A raw slice can be a value reference or a raw pointer.

<<< @/../../docs-snippets/src/guide/types/raw-slice.test.ts#raw-slice-1{ts:line-numbers}

## Using a RawSlice

The `RawSlice` type can be integrated with your contract calls. Consider the following contract that can compare and return a `RawSlice`:

<<< @/../../docs-snippets/projects/echo-raw-slice/src/main.sw#raw-slice-1{ts:line-numbers}

A `RawSlice` can be created using a native JavaScript array of numbers or Big Numbers, and sent to a Sway contract:
<<< @/../../docs-snippets/src/guide/types/raw-slice.test.ts#raw-slice-2{ts:line-numbers}
14 changes: 14 additions & 0 deletions apps/docs/src/guide/types/std-string.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# StdString

A dynamic string of variable length can be represented using the `StdString` type, also known as a Standard Lib String or `std-lib-string`. It behaves much like a dynamic string in most languages, and is essentially an array of characters.

<<< @/../../docs-snippets/src/guide/types/std-string.test.ts#std-string-1{ts:line-numbers}

## Using a StdString

The `StdString` type can be integrated with your contract calls. Consider the following contract that can compare and return a String:

<<< @/../../docs-snippets/projects/echo-std-string/src/main.sw#std-string-1{ts:line-numbers}

A string can be created using a native JavaScript string, and sent to a Sway contract:
<<< @/../../docs-snippets/src/guide/types/std-string.test.ts#std-string-2{ts:line-numbers}
27 changes: 27 additions & 0 deletions packages/abi-typegen/src/abi/types/BytesType.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { BytesType } from './BytesType';
import { StructType } from './StructType';

describe('BytesType.ts', () => {
test('should properly parse type attributes', () => {
const bytes = new BytesType({
rawAbiType: {
components: null,
typeParameters: null,
typeId: 1,
type: BytesType.swayType,
},
});

bytes.parseComponentsAttributes({ types: [] });

const suitableForBytes = BytesType.isSuitableFor({ type: BytesType.swayType });
const suitableForStruct = BytesType.isSuitableFor({ type: StructType.swayType });

expect(suitableForBytes).toEqual(true);
expect(suitableForStruct).toEqual(false);

expect(bytes.attributes.inputLabel).toEqual('Bytes');
expect(bytes.attributes.outputLabel).toEqual('Bytes');
expect(bytes.requiredFuelsMembersImports).toStrictEqual([]);
});
});
23 changes: 23 additions & 0 deletions packages/abi-typegen/src/abi/types/BytesType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { IType } from '../../types/interfaces/IType';

import { ArrayType } from './ArrayType';

export class BytesType extends ArrayType {
public static swayType = 'struct Bytes';

public name = 'bytes';

static MATCH_REGEX: RegExp = /^struct Bytes/m;

static isSuitableFor(params: { type: string }) {
return BytesType.MATCH_REGEX.test(params.type);
}

public parseComponentsAttributes(_params: { types: IType[] }) {
this.attributes = {
inputLabel: `Bytes`,
outputLabel: `Bytes`,
};
return this.attributes;
}
}
27 changes: 27 additions & 0 deletions packages/abi-typegen/src/abi/types/RawUntypedSlice.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { RawUntypedSlice } from './RawUntypedSlice';
import { StructType } from './StructType';

describe('RawUntypedSlice.ts', () => {
test('should properly parse type attributes', () => {
const rawSlice = new RawUntypedSlice({
rawAbiType: {
components: null,
typeParameters: null,
typeId: 1,
type: RawUntypedSlice.swayType,
},
});

rawSlice.parseComponentsAttributes({ types: [] });

const suitableForRawUntyped = RawUntypedSlice.isSuitableFor({ type: RawUntypedSlice.swayType });
const suitableForStruct = RawUntypedSlice.isSuitableFor({ type: StructType.swayType });

expect(suitableForRawUntyped).toEqual(true);
expect(suitableForStruct).toEqual(false);

expect(rawSlice.attributes.inputLabel).toEqual('RawUntypedSlice');
expect(rawSlice.attributes.outputLabel).toEqual('RawUntypedSlice');
expect(rawSlice.requiredFuelsMembersImports).toStrictEqual([]);
});
});
Loading

0 comments on commit f6fb12b

Please sign in to comment.