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.

Monday, 25 May 2015

Blog: Google Code shutting down; code moved to GitHub

Many previous posts link to https://code.google.com/p/illegalargumentexception/ but this resource is going away:

Hello,

Earlier today, Google announced we will be turning down Google Code Project Hosting. The service started in 2006 with the goal of providing a scalable and reliable way of hosting open source projects. Since that time, millions of people have contributed to open source projects hosted on the site.

But a lot has changed since 2006. In the past nine years, many other options for hosting open source projects have popped up, along with vibrant communities of developers. It’s time to recognize that Google Code’s mission to provide open source projects a home has been accomplished by others, such as GitHub and Bitbucket.

We will be shutting down Google Code over the coming months. Starting today, the site will no longer accept new projects, but will remain functionally unchanged until August 2015. After that, project data will be read-only. Early next year, the site will shut down, but project data will be available for download in an archive format.

etc...

The contents of the old SVN repository have been moved to https://github.com/mcdiae/iae.

Links have not been changed at this time.

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.

Wednesday, 6 May 2015

UML: authoring simple sequence diagrams

I had specific criteria for a UML sequence diagram generator:

  • Text-sourced
  • Simple
  • Off-line
  • Linux

seqdiag fits the bill. There is an interactive shell if you want to try it out before installing.

Monday, 27 April 2015

CentOS 6.6: redirecting SNMP traps from low ports to high ports with iptables

I have a Java application that processes SNMP traps. Traps arrive on port 162. Normally Java cannot listen on the low ports. You can use setcap to permit it or run as root but these introduce potential security issues.

I opted to have the Java process listen on port 1162. Changes will have to be performed as root.

Thursday, 12 March 2015

Java: handling null in getter method chains

Null is just something you need to deal with in Java. This post looks at the mechanism for handling chained method calls without causing a NullPointerException.

This post uses Java 8.

Sunday, 16 November 2014

Java: equals and hashCode performance

I wanted to benchmark KλudJe's equals/hashCode implementation against common alternatives. I used JMH 1.2 to measure performance.

Sunday, 10 August 2014

Java: easy equals/hashCode/toString (less boilerplate; no magic)

This post describes a way to implement the equals hashCode and toString methods with relative brevity using Java 8 and KλudJe.

Tuesday, 29 July 2014

I18N: dead links; Michael Kaplan's blog

Many of the links on this blog useful for Windows internationalization are dead as Microsoft has ceased hosting them. Some of the information may still be available here.

Tuesday, 22 July 2014

Java: arbitrary functional interfaces and checked exceptions in Java 8

The last couple of posts have covered how to handle exceptions with Java 8 functional interfaces. This post discusses how to handle arbitrary functional interfaces as of KλudJe 0.2.

Saturday, 19 July 2014

Java: lambdas, streams and IOException

The last post discussed exception handling with KλudJe in broad terms. This post presents a more practical example with the Stream type and I/O.