diff --git a/playground/src/examples/index.ts b/playground/src/examples/index.ts index d54101c6..42db10d3 100644 --- a/playground/src/examples/index.ts +++ b/playground/src/examples/index.ts @@ -118,6 +118,70 @@ function second(pair: Pair) returns (b) { function main() returns (word) { return second(Pair(true, 42)); } +`, + }, + ], + }, + { + id: "pattern-matching", + name: "Pattern matching", + description: "An escrow whose lifecycle is an enum stored in a contract field, driven by match.", + entry: "main.sol", + files: [ + { + path: "main.sol", + content: `import * from std; +import * from std.dispatch; +import * from std.Generic; +import * from std.StorageGeneric; + +// An escrow whose lifecycle is a sum type stored in a contract field. +enum Phase { + AwaitingPayment, + Funded(uint256), + Released(uint256) +} + +contract Escrow { + phase: Phase; + + constructor() { + phase = Phase.AwaitingPayment; + } + + function deposit(amount: uint256) public { + match (phase) { + case Phase.AwaitingPayment { + phase = Phase.Funded(amount); + } + default { + require(false, "already funded"); + } + } + } + + function release() public returns (uint256) { + match (phase) { + case Phase.Funded(amount) { + phase = Phase.Released(amount); + return amount; + } + default { + require(false, "nothing to release"); + return uint256(0); + } + } + } + + // 0 = awaiting payment, 1 = funded, 2 = released + function status() public returns (uint256) { + match (phase) { + case Phase.AwaitingPayment { return uint256(0); } + case Phase.Funded(_) { return uint256(1); } + case Phase.Released(_) { return uint256(2); } + } + } +} `, }, ],