Skip to content

Commit

Permalink
Mod exercises (foundry-rs#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
shramee authored May 7, 2023
1 parent c3a4cde commit cae0f33
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
30 changes: 30 additions & 0 deletions exercises/modules/modules1.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// We are writing an app for a restaurant,
// but take_order functions are not being called correctly.
// Can you fix this?

// I AM NOT DONE

mod restaurant {
fn take_order() -> felt252 {
'order_taken'
}
}

#[test]
fn test_mod_fn() {
// Fix this line to call take_order function from module
let order_result = take_order();

assert(order_result == 'order_taken', 'Order not taken');
}


mod tests {
#[test]
fn test_super_fn() {
// Fix this line to call take_order function
let order_result = take_order();

assert(order_result == 'order_taken', 'Order not taken');
}
}
56 changes: 56 additions & 0 deletions exercises/modules/modules2.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// I AM NOT DONE
// These modules have some issues, can you fix?
// Run `starklings hint modules2` or `hint` watch command for a hint.

use debug::PrintTrait;
const YEAR: felt252 = 2050;

mod order {
#[derive(Copy, Drop)]
struct Order {
name: felt252,
year: felt252,
made_by_phone: bool,
made_by_email: bool,
item: felt252,
}

fn new_order( name: felt252, made_by_phone: bool, item: felt252 ) -> Order {
Order {
name,
year: YEAR,
made_by_phone,
made_by_email: ! made_by_phone,
item,
}
}
}

mod order_utils {
fn dummy_phoned_order( name: felt252 ) -> Order {
new_order( name, true, 'item_a' )
}

fn dummy_emailed_order( name: felt252 ) -> Order {
new_order( name, false, 'item_a' )
}

fn order_fees( order: Order ) -> felt252 {
if order.made_by_phone {
return 500;
}

200
}
}

#[test]
fn test_array() {
let order1 = order_utils::dummy_phoned_order( 'John Doe' );
let fees1 = order_utils::order_fees( order1 );
assert( fees1 == 500, 'Order fee should be 500');

let order2 = order_utils::dummy_emailed_order( 'Jane Doe' );
let fees2 = order_utils::order_fees( order2 );
assert( fees2 == 200, 'Order fee should be 200');
}
76 changes: 76 additions & 0 deletions exercises/modules/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# Modules

Modules allow creating individual scopes and organise your code better. Read about [modules in cairo book](https://cairo-book.github.io/ch06-02-defining-modules-to-control-scope.html).

Here's some code to show modules at play,

## Declaring modules

Modules can be declared in two way,

| Code | Description |
| --------------- | ---------------------------- |
| `mod filename;` | Module from a filename.cairo |
| `mod { ... }` | Inline module code in braces |

In the exercises we'll use inline modules, but the behaviour is identical.

### `lib.cairo`

```rust
// Module from a file
mod restaurant;

fn main() {
// ...
}
```

### `restaurant.cairo`

```rust
fn add_to_waitlist() {}
fn seat_at_table() {}

// Inline modules
mod serving {
fn take_order() {}
fn serve_order() {}
}

mod checkout {
fn get_bill() {}
fn collect_payment() {}
}
```

## Using stuff in modules

| Keyword | Description | Example |
| ------- | ------------------- | ------------------------- |
| `super` | Access parent scope | `super::my_module::my_fn` |
| `use` | Create shortcuts | `use my_module::my_fn` |

### `lib.cairo`

```rust
// ...
use restaurant::seat_at_table; // Creates shortcut to seat_at_table
use restaurant::serving::serve_order; // Another shortcut
use restaurant::checkout; // Shortcut to a module


fn main() {
restaurant::add_to_waitlist();
seat_at_table(); // Shortcut thanks to use

restaurant::serving::take_order();
serve_order(); // Via shortcut
}

mod cutomer_checkout {
fn start() {
super::checkout::collect_payment();
}
}
```
17 changes: 17 additions & 0 deletions info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,23 @@ If you're having trouble updating the distance value in the `Fish` and `Dog` imp
3. Reconstruct `self` with the updated variables (`self = MyStruct { ... }`)
"""

# MODULES

[[exercises]]
name = "modules1"
path = "exercises/modules/modules1.cairo"
mode = "test"
hint = """"""

[[exercises]]
name = "modules2"
path = "exercises/modules/modules2.cairo"
mode = "test"
hint = """
While using functions/structs etc from outside the module,
you can use full paths or `use` keyword to create shortcuts.
"""

# STARKNET

[[exercises]]
Expand Down

0 comments on commit cae0f33

Please sign in to comment.