Skip to content

Commit

Permalink
New challenge: Primitive data types (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodesdev authored Jun 9, 2024
1 parent 531a1fe commit ae2c623
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions challenges/challenges.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,18 @@
"created_at": "2024-06-09T00:00:00Z",
"updated_at": "2024-06-09T00:00:00Z"
},
{
"id": 25,
"title": "Primitive Data Types",
"slug": "primitive-data-types",
"short_description": "Get familiar with primitive data types in Rust by defining and annotating variables.",
"language": "RUST",
"difficulty": "BEGINNER",
"track": "RUST_BASICS",
"tags": ["data types", "basics"],
"created_at": "2024-06-09T00:00:00Z",
"updated_at": "2024-06-09T00:00:00Z"
},
{
"id": 2,
"title": "Character counting string",
Expand Down
7 changes: 7 additions & 0 deletions challenges/primitive-data-types/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "primitive-data-types"
version = "0.1.0"
edition = "2021"

[dev-dependencies]
syntest = { version = "0.1.0", path = "../../crates/syntest" }
29 changes: 29 additions & 0 deletions challenges/primitive-data-types/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Rust is a **statically-typed** language, which means that every variable must have a specific type. Rust's type system is designed to be safe and to prevent many common errors that occur in other languages. In this challenge, you will learn about some of the basic primitive data types in Rust, such as integers, floating-point numbers, booleans, and characters.

Understanding how to declare and use these basic data types is fundamental to writing effective Rust code. This challenge will guide you through defining variables with specific types and initializing them.

## Your task

1. Define variable `x` with type `u8`
2. Define variable `y` with type `f64`
3. Define variable `z` with type `bool`
4. Define variable `a` with type `char`

Each of these variables **should be annotated** with their respective types and initialized with specific **values of your choice**.

## Requirements

- Every variable **must be annotated** with its type.
- Initialize each variable with any value of your choice of the correct type.

## Explanation of Data Types

- **Integer** `(u8)`: Represents an `8-bit` unsigned integer.
- **Floating-point number** `(f64)`: Represents a `64-bit` **floating-point number**.
- **Boolean** `(bool)`: Represents a `boolean` value, which can be either `true` or `false`.
- **Character** `(char)`: Represents a single Unicode **scalar** value.

## Hints

- Use the `let` keyword to define a variable.
- Annotate the variable's type by specifying `let variable_name: type = `.
8 changes: 8 additions & 0 deletions challenges/primitive-data-types/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#[allow(warnings)]

pub fn data_types() {
let x: u8 = 42;
let y: f64 = 3.224242422424;
let z: bool = false;
let a: char = '7';
}
9 changes: 9 additions & 0 deletions challenges/primitive-data-types/src/starter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub fn data_types() {
// 1. Define variable `x` of type `u8`

// 2. Define variable `y` of type `f64`

// 3. Define variable `z` of type `bool`

// 4. Define variable `a` of type `char`
}
51 changes: 51 additions & 0 deletions challenges/primitive-data-types/tests/tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#[cfg(test)]

mod tests {
use primitive_data_types::*;
use syntest::{parse_quote, Pat, Stmt, Syntest};

#[test]
fn test_compiles() {
data_types();
}

#[test]
fn test_annotations() {
let syntest = Syntest::from("./src/lib.rs");

let pats_actual = syntest.get_pats("data_types");
let stmts_expected: [Stmt; 4] = [
parse_quote! {
let x: u8 = 42;
},
parse_quote! {
let y: f64 = 3.14;
},
parse_quote! {
let z: bool = true;
},
parse_quote! {
let a: char = 'R';
},
];

let mut expected_count = 0;
for (pat_actual, stmt_expected) in pats_actual.iter().zip(stmts_expected.iter()) {
if let Stmt::Local(local_expected) = stmt_expected {
if let Pat::Type(type_expected) = &local_expected.pat {
if let Pat::Ident(ident_expected) = &*type_expected.pat {
let pat_expected = &local_expected.pat;
assert_eq!(
pat_actual, pat_expected,
"Wrong type annotated for {}",
ident_expected.ident
);
expected_count += 1;
}
}
}
}

assert_eq!(expected_count, stmts_expected.len());
}
}
3 changes: 1 addition & 2 deletions crates/syntest/src/syn.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
pub use syn::parse_quote;
pub use syn::Type;
pub use syn::*;
20 changes: 20 additions & 0 deletions crates/syntest/src/syntest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,26 @@ impl Syntest {
_ => 0,
}
}

pub fn get_stmts(&self, fn_name: &str) -> Vec<Stmt> {
let mut locals = Vec::new();

self.func_stmts(fn_name, |_, stmt| locals.push(stmt.clone()));

locals
}

pub fn get_pats(&self, fn_name: &str) -> Vec<Pat> {
let mut locals = Vec::new();

self.func_stmts(fn_name, |_, stmt| {
if let Stmt::Local(local) = stmt {
locals.push(local.pat.clone());
}
});

locals
}
}

impl From<&str> for Syntest {
Expand Down

0 comments on commit ae2c623

Please sign in to comment.