Records
A record is a struct. Record literals use { field = value; }, and stored records can be updated one field at a time.
records.lithe
(* Records are structs. Storage lays them out exactly as Solidity would. *)
type Todo is record {
priority : uint8;
done : bool;
}
type Point is record {
x : uint128;
y : uint128;
}
storage is record {
todos : map(uint, Todo);
count : uint;
origin : Point;
}
external function add(const priority : uint8) is {
storage.todos[storage.count] := { priority = priority; done = false; };
storage.count := storage.count + 1;
}
(* Write one field of a record stored in a map. *)
external function toggle(const id : uint) is {
storage.todos[id].done := not storage.todos[id].done;
}
external view function get(const id : uint) : Todo is
storage.todos[id]
external function move(const x : uint128; const y : uint128) is {
storage.origin.x := x;
storage.origin.y := y;
}
external view function x() : uint128 is
storage.origin.x
(* A function can return a record, like any other value. *)
pure function swapped(const p : Point) : Point is { x = p.y; y = p.x; }
external function reflect() is {
storage.origin := swapped(storage.origin);
}
external view function reflectedX() : uint128 is
swapped(storage.origin).x- A record literal takes its type from context: a storage slot, an annotation, or a parameter.
getreturns a record, which the ABI flattens into named outputs(uint8 priority, bool done), like a Solidity struct getter.- Records inside maps must be made of word-sized fields, with no
stringorbytes. swappedreturns a record.reflectstores the whole result at once, andreflectedXreads one field straight off the call. A whole-record store builds the new value before writing any of it, soswappedsees the oldorigin.

