---
# System prepended metadata

title: Rust Tutorial
tags: [Active]

---

# Rust Tutorial

###### tags: `Active`

## checkpoint 1
```=Rust
use std::num::ParseIntError;

#[derive(PartialEq, Debug)]
enum ParsePosNonzeroError {
    Creation(CreationError),
    ParseInt(ParseIntError)
}

impl ParsePosNonzeroError {
    fn from_creation(err: CreationError) -> ParsePosNonzeroError {
        todo!()
    }
}

fn parse_pos_nonzero(s: &str)
    -> Result<PositiveNonzeroInteger, ParsePosNonzeroError>
{
    todo!()
}

#[derive(PartialEq, Debug)]
struct PositiveNonzeroInteger(u64);

#[derive(PartialEq, Debug)]
enum CreationError {
    Negative,
    Zero,
}

impl PositiveNonzeroInteger {
    fn new(value: i64) -> Result<PositiveNonzeroInteger, CreationError> {
        todo!()
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_parse_error() {
        // We can't construct a ParseIntError, so we have to pattern match.
        assert!(matches!(
            parse_pos_nonzero("not a number"),
            Err(ParsePosNonzeroError::ParseInt(_))
        ));
    }

    #[test]
    fn test_negative() {
        assert_eq!(
            parse_pos_nonzero("-555"),
            Err(ParsePosNonzeroError::Creation(CreationError::Negative))
        );
    }

    #[test]
    fn test_zero() {
        assert_eq!(
            parse_pos_nonzero("0"),
            Err(ParsePosNonzeroError::Creation(CreationError::Zero))
        );
    }

    #[test]
    fn test_positive() {
        let x = PositiveNonzeroInteger::new(42);
        assert!(x.is_ok());
        assert_eq!(parse_pos_nonzero("42"), Ok(x.unwrap()));
    }
}
```


## checkpoint 2
```=Rust
trait AppendBar {
    fn append_bar(self) -> Self;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn is_foo_bar() {
        assert_eq!(String::from("Foo").append_bar(), String::from("FooBar"));
    }

    #[test]
    fn is_bar_bar() {
        assert_eq!(
            String::from("").append_bar().append_bar(),
            String::from("BarBar")
        );
    }
    
    #[test]
    fn test_string() {
        let s = String::from("Foo");
        let s = s.append_bar();
        println!("s: {}", s);
    }
    
    #[test]
    fn is_vec_pop_eq_bar() {
        let mut foo = vec![String::from("Foo")].append_bar();
        assert_eq!(foo.pop().unwrap(), String::from("Bar"));
        assert_eq!(foo.pop().unwrap(), String::from("Foo"));
    }
}
```

## checkpoint3
```=Rust
/// A counter type
#[derive(Debug)]
struct AtomicCounter; // add fields to me!
impl AtomicCounter {
    fn new(init: i32) -> Self {
        todo!() // initialize 
    }
    fn add(&self) -> i32 {
        todo!() // add 1
    }
    fn sub(&self) -> i32 {
        todo!() // subtract 1
    }
    fn get(&self) -> i32 {
        todo!() // get the counter value
    }
}


#[cfg(test)]
mod test {
    use crate::AtomicCounter;
    use std::thread;
    use std::sync::Arc;
    #[test]
    fn t1() {
        let ctr = AtomicCounter::new(0);
        assert_eq!(1, ctr.add())
    }
    
    #[test]
    fn t2() {
        let ctr = Arc::new(AtomicCounter::new(0));
        let x = ctr.clone();
        let _ = thread::spawn(move || {
            assert_eq!(1, x.add());
        }).join();
        assert_eq!(0, ctr.sub());
    }
    
    #[test]
    fn t3() {
        let ctr = Arc::new(AtomicCounter::new(0));
        assert_eq!(0, ctr.get());
        (0..10).map(|_| {
            let x = ctr.clone();
            thread::spawn(move || {
                x.add();
            })
        }).for_each(|x| x.join().unwrap());
        assert_eq!(10, ctr.get());
    }
}
```