Skip to content

Commit

Permalink
Add semi-structured-logs + add missing authors
Browse files Browse the repository at this point in the history
  • Loading branch information
Nenad committed Jun 19, 2024
1 parent ed7c803 commit 557d10c
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 1 deletion.
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@
],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "semi-structured-logs",
"name": "semi-structured-logs",
"uuid": "4ca5087f-0128-4845-89a8-a2fa7791ed98",
"practices": [
"enums",
"match-basics"
],
"prerequisites": [],
"difficulty": 1
}
]
},
Expand Down
4 changes: 3 additions & 1 deletion exercises/practice/leap/.meta/config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"authors": [],
"authors": [
"misicnenad"
],
"files": {
"solution": [
"src/lib.cairo",
Expand Down
13 changes: 13 additions & 0 deletions exercises/practice/semi-structured-logs/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Hints

## General

- [The Cairo Book - Enums][tcb-enums]
- [The Cairo Book - Match][tcb-match]

## 1. Emit semi-structured messages

- `match` comes in handy when working with enums. In this case, see how you might use it when figuring how what kind of log message to generate.

[tcb-enums]: https://book.cairo-lang.org/ch06-01-enums.html
[tcb-match]: https://book.cairo-lang.org/ch06-02-the-match-control-flow-construct.html
36 changes: 36 additions & 0 deletions exercises/practice/semi-structured-logs/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Instructions

In this exercise you'll be generating semi-structured log messages.

## Emit semi-structured messages

You'll start with some stubbed functions and the following enum:

```rust
#[derive(Drop, Clone, PartialEq, Debug)]
pub enum LogLevel {
Info,
Warning,
Error,
Debug
}
```

Your goal is to emit a log message as follows: `"[<LEVEL>]: <MESSAGE>"`.
You'll need to implement functions that correspond with log levels.

For example, the below snippet demonstrates an expected output for the `log` function.

```rust
log(LogLevel::Error, "Stack overflow")
// Returns: "[ERROR]: Stack overflow"
```

And for `info`:

```rust
info("Timezone changed")
// Returns: "[INFO]: Timezone changed"
```

Have fun!
3 changes: 3 additions & 0 deletions exercises/practice/semi-structured-logs/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Introduction

Enums, short for enumerations, are a type that limits all possible values of some data. The possible values of an `enum` are called variants. Enums also work well with `match` and other control flow operators to help you express intent in your Cairo programs.
18 changes: 18 additions & 0 deletions exercises/practice/semi-structured-logs/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"authors": [
"misicnenad"
],
"files": {
"solution": [
"src/lib.cairo",
"Scarb.toml"
],
"test": [
"src/tests.cairo"
],
"example": [
".meta/example.cairo"
]
},
"blurb": "Learn enums while building a logging utility."
}
31 changes: 31 additions & 0 deletions exercises/practice/semi-structured-logs/.meta/example.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#[derive(Clone, PartialEq, Debug)]
enum LogLevel {
Info,
Warning,
Error,
Debug,
}

fn log(level: LogLevel, message: ByteArray) -> ByteArray {
match level {
LogLevel::Info => info(message),
LogLevel::Warning => warn(message),
LogLevel::Error => error(message),
LogLevel::Debug => format!("[DEBUG]: {message}"),
}
}

fn info(message: ByteArray) -> ByteArray {
format!("[INFO]: {message}")
}

fn warn(message: ByteArray) -> ByteArray {
format!("[WARNING]: {message}")
}

fn error(message: ByteArray) -> ByteArray {
format!("[ERROR]: {message}")
}

#[cfg(test)]
mod tests;
4 changes: 4 additions & 0 deletions exercises/practice/semi-structured-logs/Scarb.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "semi_structured_logs"
version = "0.1.0"
edition = "2023_11"
28 changes: 28 additions & 0 deletions exercises/practice/semi-structured-logs/src/lib.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// various log levels
#[derive(Drop, Clone, PartialEq, Eq, Debug)]
enum LogLevel {
Info,
Warning,
Error,
Debug
}

/// primary function for emitting logs
fn log(level: LogLevel, message: ByteArray) -> ByteArray {
panic!("return a message for the given log level")
}

fn info(message: ByteArray) -> ByteArray {
panic!("return a message for info log level")
}

fn warn(message: ByteArray) -> ByteArray {
panic!("return a message for warn log level")
}

fn error(message: ByteArray) -> ByteArray {
panic!("return a message for error log level")
}

#[cfg(test)]
mod tests;
36 changes: 36 additions & 0 deletions exercises/practice/semi-structured-logs/src/tests.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use semi_structured_logs::{error, info, log, warn, LogLevel};

#[test]
fn emits_info() {
assert_eq!(info("Timezone changed"), "[INFO]: Timezone changed");
}

#[test]
fn emits_warning() {
assert_eq!(warn("Timezone not set"), "[WARNING]: Timezone not set");
}

#[test]
fn emits_error() {
assert_eq!(error("Disk full"), "[ERROR]: Disk full");
}

#[test]
fn log_emits_info() {
assert_eq!(log(LogLevel::Info, "Timezone changed"), "[INFO]: Timezone changed");
}

#[test]
fn log_emits_warning() {
assert_eq!(log(LogLevel::Warning, "Timezone not set"), "[WARNING]: Timezone not set");
}

#[test]
fn log_emits_error() {
assert_eq!(log(LogLevel::Error, "Disk full"), "[ERROR]: Disk full");
}

#[test]
fn add_a_variant() {
assert_eq!(log(LogLevel::Debug, "reached line 123"), "[DEBUG]: reached line 123",);
}

0 comments on commit 557d10c

Please sign in to comment.