cqc 0.3.3

An implementation of the CQC interface.
Documentation

CQC

Latest version Documentation License

A sans-io Rust implementation of the CQC interface.

CQC in action

The following example will create a qubit on one node and send it to another node. Before running the example below start up the SimulaQron nodes with $NETSIM/run/startAll.sh --nrnodes 2.

extern crate bincode;
extern crate cqc;

use cqc::builder;
use cqc::hdr;
use std::net;

fn main() {
    // Initialise local node `localhost:8803`.
    let hostname = String::from("localhost");
    let local_port: u16 = 8803;

    // Set up remote node `127.0.0.1:8804`.
    let remote_host: u32 = u32::from(net::Ipv4Addr::new(127, 0, 0, 1));
    let remote_port: u16 = 8804;

    // Initialise application state with ID 10.
    let app_id: u16 = 10;
    let builder = builder::Builder::new(app_id);
    let mut coder = bincode::config();
    coder.big_endian();

    // Create, and send a qubit from `localhost:8803` to `localhost:8804`.
    {
        // Open connection to local node.
        let stream = net::TcpStream::connect((hostname.as_str(), local_port))
            .expect("Connect failed");

        // Create the qubit.
        let request = builder.cmd_new(0, hdr::CmdOpt::empty());
        coder.serialize_into(&stream, &request).expect(
            "Sending failed",
        );

        // Wait for confirmation of creation.
        let response: cqc::Response = coder.deserialize_from(&stream).expect("Receive failed");

        // Read the created qubit ID.
        let note = response.notify.get_notify_hdr();
        let qubit_id = note.qubit_id;

        // Send the qubit to the remote node.
        let request = builder.cmd_send(
            qubit_id,
            *hdr::CmdOpt::empty().set_notify(),
            builder::RemoteId {
                remote_app_id: app_id,
                remote_node: remote_host,
                remote_port: remote_port,
            },
        );
        coder.serialize_into(&stream, &request).expect(
            "Sending failed",
        );

        // Wait for confirmation.
        let response: cqc::Response = coder.deserialize_from(&stream).expect("Receive failed");
        assert!(response.cqc_hdr.msg_type.is_done(), "Unexpected response");
    }

    // Receive the qubit on the remote node, `localhost:8804`.
    {
        // Open connection to local node.
        let stream = net::TcpStream::connect((hostname.as_str(), remote_port))
            .expect("Connect failed");

        // Send a request to receive a qubit.
        let request = builder.cmd_recv(0, hdr::CmdOpt::empty());
        coder.serialize_into(&stream, &request).expect(
            "Sending failed",
        );

        // Receive a response.
        let response: cqc::Response = coder.deserialize_from(&stream).expect("Receive failed");
        assert!(response.cqc_hdr.msg_type.is_recv(), "Unexpected response");
        let note = response.notify.get_notify_hdr();
        let qubit_id = note.qubit_id;

        println!("Received qubit ID: {}", qubit_id);
    }
}

Design goals

The following goals drive the design of the cqc crate:

  • The user should be able to create any valid packet

    This goal is achieved by having correct struct definitions for the different CQC headers.

  • It should be difficult, though preferably impossible, to create invalid packets

    The second goal is achieved by using Rust's typing system as much as possible, especially enums for fields with only a small set of possible values. Furthermore a builder module is provided which guarantees correct CQC packets.

  • Decoding should raise errors if unrecognised values are detected

    This is achieved through a combination of type definitions and deserialization implementations.

  • No assumption about the user's run-time should be made

    The library is sans-io and only provides a very plain encoder and decoder as an example. The intention is that the user builds packets using the cqc library, but I/O is their responsibility. The Serialize and Deserialize traits are implemented so that the user can simply use bincode for encode/decode.

Limitations

  • Factory and Sequence Headers are not currently fully supported.
  • Encode/decode is implemented for client-side operations.

Usage

Add this to your Cargo.toml:

[dependencies]
cqc = "0.3"

and this to your source file:

extern crate cqc;