Выбрать главу

return;

},

};

// parse the command

match &cmd[..] {

"increase" => increase(number),

"decrease" => decrease(number),

_ => {

eprintln!("error: invalid command");

help();

},

}

},

// all the other cases

_ => {

// show a help message

help();

}

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

$ ./match_args Rust

This is not the answer.

$ ./match_args 42

This is the answer!

$ ./match_args do something

error: second argument not an integer

usage:

match_args <string>

Check whether given string is the answer.

match_args {increase|decrease} <integer>

Increase or decrease given integer by one.

$ ./match_args do 42

error: invalid command

usage:

match_args <string>

Check whether given string is the answer.

match_args {increase|decrease} <integer>

Increase or decrease given integer by one.

$ ./match_args increase 42

43

Rust provides a Foreign Function Interface (FFI) to C libraries. Foreign functions must be declared inside an extern block annotated with a #[link] attribute containing the name of the foreign library.

use std::fmt;

// this extern block links to the libm library

#[link(name = "m")]

extern {

// this is a foreign function

// that computes the square root of a single precision complex number

fn csqrtf(z: Complex) -> Complex;

fn ccosf(z: Complex) -> Complex;

}

// Since calling foreign functions is considered unsafe,

// it's common to write safe wrappers around them.

fn cos(z: Complex) -> Complex {

unsafe { ccosf(z) }

}

fn main() {

// z = -1 + 0i

let z = Complex { re: -1., im: 0. };

// calling a foreign function is an unsafe operation

let z_sqrt = unsafe { csqrtf(z) };

println!("the square root of {:?} is {:?}", z, z_sqrt);

// calling safe API wrapped around unsafe operation

println!("cos({:?}) = {:?}", z, cos(z));

}

// Minimal implementation of single precision complex numbers

#[repr(C)]

#[derive(Clone, Copy)]

struct Complex {

re: f32,

im: f32,

}

impl fmt::Debug for Complex {

fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

if self.im < 0. {

write!(f, "{}-{}i", self.re, -self.im)

} else {

write!(f, "{}+{}i", self.re, self.im)

}

}

}

Rust is a programming language that cares a lot about correctness and it includes support for writing software tests within the language itself.

Testing comes in three styles:

   • Unit testing.

   • Doc testing.

   • Integration testing.

Also Rust has support for specifying additional dependencies for tests:

   • Dev-dependencies

   • The Book chapter on testing

   • API Guidelines on doc-testing

Tests are Rust functions that verify that the non-test code is functioning in the expected manner. The bodies of test functions typically perform some setup, run the code we want to test, then assert whether the results are what we expect.

Most unit tests go into a tests mod with the #[cfg(test)] attribute. Test functions are marked with the #[test] attribute.

Tests fail when something in the test function panics. There are some helper macros:

   • assert!(expression) - panics if expression evaluates to false.

   • assert_eq!(left, right) and assert_ne!(left, right) - testing left and right expressions for equality and inequality respectively.

pub fn add(a: i32, b: i32) -> i32 {

a + b

}

// This is a really bad adding function, its purpose is to fail in this

// example.

#[allow(dead_code)]

fn bad_add(a: i32, b: i32) -> i32 {

a - b

}

#[cfg(test)]

mod tests {

// Note this useful idiom: importing names from outer (for mod tests) scope.