Showing posts with label Rust. Show all posts
Showing posts with label Rust. Show all posts

Saturday, 4 July 2015

Rust: RustDT IDE on Linux with Eclipse Mars

This is a quick guide to setting up an IDE for Rust using RustDT. Familiarity with Linux and root access is assumed. Modify commands to suit your preferences, paths, and/or the latest versions.

Stack:

  • Host: Debian 8.1.0 amd64 lxde (debian-live-8.1.0-amd64-lxde-desktop.iso)
  • Eclipse: Mars; JDK 8 runtime
  • Rust: 1.1.0

Documentation:

Tuesday, 26 May 2015

Rust: print the program arguments

A simple example using Cargo in Rust 1.0 on Linux.

Install Rust if you haven't. Create a project:

$ cargo new hello --bin

This will create the files:

hello/Cargo.toml
hello/src/main.rs

Replace the contents of main.rs with:

use std::env;

fn main() {
  for argument in env::args() {
    println!("Hello, {}!", argument);
  }
}

From the hello directory run:

$ cargo run World Kitty "to my little friend, Al Pacino"
     Running `target/debug/hello World Kitty to my little friend, Al Pacino`
Hello, target/debug/hello!
Hello, World!
Hello, Kitty!
Hello, to my little friend, Al Pacino!

Rust provides the executable as the zeroth argument target/debug/hello. The arguments passed to the application start at index 1.

Friday, 15 May 2015

Rust: is ready to roll (1.0.0 released)

$ sudo ./install.sh 
install: creating uninstall script at /usr/local/lib/rustlib/uninstall.sh
install: installing component 'rustc'
install: installing component 'cargo'
install: installing component 'rust-docs'

    Rust is ready to roll.

$ rustc --version
rustc 1.0.0 (a59de37e9 2015-05-13) (built 2015-05-14)

Rust has been released. The sample 1.0.0-beta.4 code in previous posts still passes cargo clean and cargo test.

Wednesday, 13 May 2015

Rust: send and receive on localhost with UDP

UDP it is the simple cousin of TCP. You send a message off into the ether, you might listen a period of time for a response, and the payloads are small enough to fit in a packet.

This post looks at sending and receiving packets in Rust.

Rust: start thread & return value on finish

Rust threads are relatively easy to spawn and pass results back from.

use std::thread;

pub fn add_in_future(i1: i32, i2: i32) -> i32 {
  let handle = thread::spawn(move || {
    i1 + i2
  });
  handle.join().unwrap()
}

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

  #[test]
  fn test_future() {
    let expected = 3;
    let actual = add_in_future(1, 2);
    assert_eq!(expected, actual);
  }
}

The add_in_future function sums two numbers in a separate thread. Then the originating thread consumes the result. The move keyword moves ownership of variables to the new thread.

This post is just a code snippet written by someone getting started. No promises are made about code quality. Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

Rust: serializing structs to bytes

Back when I wrote C code for platform-dependent binary formats it was fairly common to perform stream I/O with structs and unions. This post looks at similar functionality in Rust.

use std::mem;

#[allow(dead_code)]
pub struct Ser {
  prop: u32
}

pub fn to_bytes(ser: Ser) -> [u8; 4] {
  unsafe { mem::transmute_copy::<Ser, [u8; 4]>(&ser) }
}

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

  #[test]
  fn test_to_bytes() {
    let instance = Ser { prop: 0x0A0B0C0D };
    let bigend = Ser { prop: instance.prop.to_be() };
    let actual = to_bytes(bigend);
    let expected: [u8; 4] = [0xA, 0xB, 0xC, 0xD];
    assert_eq!(expected, actual);
  }
}

Rust: the size of a struct

This code determines the size of a data structure in byte terms.

use std::mem;

#[allow(dead_code)]
pub struct AStruct {
  prop: u32
}

pub fn size_of_a_struct() -> usize {
  mem::size_of::<AStruct>()
}

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

  #[test]
  fn test_size() {
    let expected = 4 as usize;
    assert_eq!(expected, size_of_a_struct());
  }
}

Rust provides the size_of function to determine the size of a type.

This post is just a code snippet written by someone getting started. No promises are made about code quality. Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

Rust: byte array to hex String

This code allows you to express arbitrary octet sequences as hex.

pub fn to_hex_string(bytes: Vec<u8>) -> String {
  let strs: Vec<String> = bytes.iter()
                               .map(|b| format!("{:02X}", b))
                               .collect();
  strs.connect(" ")
}

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

  #[test]
  fn test_to_hex_string() {
    let bytes: Vec<u8> = vec![0xFF, 0, 0xAA];
    let actual = to_hex_string(bytes);
    assert_eq!("FF 00 AA", actual);
  }
}

This function turns a byte vector into a space-delimited hex string using an iterator to map the values.

This post is just a code snippet written by someone getting started. No promises are made about code quality. Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

Rust: network byte order

Languages on different architectures might serialize the 32-bit unsigned int 15 as the byte sequences 00 00 00 0F (big-endian) or 0F 00 00 00 (little-endian) but network protocols generally prefer the former.

pub fn to_network_byte_order(n: u32) -> u32 {
  n.to_be()
}

pub fn from_network_byte_order(n: u32) -> u32 {
  u32::from_be(n)
}

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

  #[test]
  fn test_to_network_byte_order() {
    let expected: u32 = 0xFFAABBCC;
    let nbo = to_network_byte_order(expected);
    if cfg!(target_endian = "big") {
      assert_eq!(expected, nbo);
    } else {
      assert_eq!(expected.swap_bytes(), nbo);
    }
    let actual = from_network_byte_order(nbo);
    assert_eq!(expected, actual);
  }
}

u32 is a 32-bit unsigned integer; i32 is the signed version.

This post is just a code snippet written by someone getting started. No promises are made about code quality. Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

Rust: UTF-8 byte array to String

Rust has a string type that mandates UTF-8 for strings but at some point you need to turn raw octets into structures you can treat as character data.

pub fn utf8_to_string(bytes: &[u8]) -> String {
  let vector: Vec<u8> = Vec::from(bytes);
  String::from_utf8(vector).unwrap()
}

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

  #[test]
  fn test_to_string() {
    let bytes: [u8; 7] = [0x55, 0x54, 0x46, 0x38, 0, 0, 0];
    let len: usize = 4;
    let actual = utf8_to_string(&bytes[0..len]);
    assert_eq!("UTF8", actual);
  }
}

The utf8_to_string function turns some octets into a String. Note the lack of semicolon on the last line - this indicates that the line returns a value. The ampersands indicate that the function is borrowing the variable. Rust has strong opinions on ownership - expect compile errors if you do not understand this concept.

Rust comes packages with the Cargo build system. I've in-lined my unit tests to exercise the functions I write. assert_eq! is a macro. Note that I've tried out a slice in my test to truncate the trailing zeroes.

This post is just a code snippet written by someone getting started. No promises are made about code quality. Version: rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

Sunday, 10 May 2015

Rust: first look

Rust is approaching its 1.0 release.

Rust is a systems programming language that runs blazingly fast, prevents almost all crashes*, and eliminates data races.

* In theory. Rust is a work-in-progress and may do anything it likes up to and including eating your laundry.

Rust has been under public development for a number of years. Many search engine results will lead to obsolete code. That might include this post. I have tried to stick to APIs marked stable but verify against the official documentation. The documentation on www.rust-lang.org is currently incomplete but it is the best starting point.

Version info:

$ rustc --version
rustc 1.0.0-beta.4 (850151a75 2015-04-30) (built 2015-04-30)

How I approached getting started with Rust:

  • Decide on an application to write (a simple UDP test client)
  • Decompose it into a list of parts
  • Figure out how to do each one in turn

A laundry list of disjointed code samples follow in subsequent posts.

2015-05-13: post has been split up into multiple posts for easier reference; use the rust-lang tag to filter.