Better APIs using Rust's Type System: Follow-Up

Datetime:2016-08-22 23:58:57         Topic: Rust          Share        Original >>
Here to See The Original Article!!!

Thelast blog post I wrote about nicer APIs in Rust got some interesting feedback on .

One important thing I forgot to mention was that all the phantom data stuff is zero-sized - it only exists at compile time and has no runtime overhead at all. The compiler will optimize it away completely. (Thanks, Steve Klabnik )

Another person mentioned that Into can be used to generalize the state transitions:

Unfortunately, Into isn't allowed to fail and therefore isn't able to implement many common transitions. As this is a quite common scenario, Rust will get TryFrom and TryInto in the near future. These traits have the same semantics as From and Into , but allow to return a custom error for the failure case.

Using these, it's possible to implement the example from the earlier post like this:


use std::marker::PhantomData;
use std::convert::TryFrom;

struct Connection<T> {
  phantom: PhantomData<T>

struct Disconnected;
struct Connected;

type ClosedConn = Connection<Disconnected>;
type OpenConn   = Connection<Connected>;

impl ClosedConn {
  fn new() -> ClosedConn {
    Connection { phantom: PhantomData }

enum TransitionErr {

impl TryFrom<ClosedConn> for OpenConn {
  type Err = TransitionErr;

  fn try_from(_closed: ClosedConn) -> Result<Self, Self::Err> {
    //Try to connect, for now just return an error

impl TryFrom<OpenConn> for ClosedConn {
  type Err = TransitionErr;

  fn try_from(_open: OpenConn) -> Result<Self, Self::Err> {
    // Disconnect
    Ok(ClosedConn { phantom: PhantomData })

fn main() {
  let x = Connection::new();
  let x = OpenConn::try_from(x).expect("Failed to connect");
  let x = ClosedConn::try_from(x).expect("Failed to disconnect");


Put your ads here, just $200 per month.