5个版本

使用旧的Rust 2015

0.1.4 2017年2月7日
0.1.3 2017年1月5日
0.1.2 2016年5月4日
0.1.1 2016年4月9日
0.1.0 2016年3月31日

#1 in #i8

每月26次下载
用于 2 crates

MIT/Apache

41KB
1K SLoC

td_rp

tickbh rust二进制协议

Build Status

支持类型

基本类型包括 "u8", "i8", "u16", "i16", "u32", "i32", "float", "string", "raw", "map"

数组类型包括 "u8[]", "i8[]", "u16[]", "i16[]", "u32[]", "i32[]", "float[]", "string[]", "raw[]", "map[]"

数据详细

数据将按照如下格式进行格式化:Id, Type, Data,存储时采用小端字节序,Id为2字节,Type为2字节

  • "u8", "i8" -- 1字节
  • "u16", "i16" -- 2字节
  • "u32", "i32", "float" -- 4字节,float解码使用i32除以1000
  • "string", "raw" -- 2字节长度,长度字节的数据
  • map -- key始终编码为字符串,包含id,type,value是基本值,末尾键type为nil
  • array -- 写入基本数据,以id = 0,type = 0结束

示例数据u8

extern crate td_proto_rust;
use td_rp::{Value, Config, Buffer};

fn test_head_field(buffer : &mut Buffer, index : u16, t : u16) {
    // first index bytes
    let data: &mut [u8; 2] = &mut [0, 0];
    let size = buffer.read(data).unwrap();
    assert_eq!(size, 2);
    let val = u16::from_le(unsafe { mem::transmute::<[u8;2], u16>(*data) });
    assert_eq!(val, index);

    // first type bytes
    let size = buffer.read(data).unwrap();
    assert_eq!(size, 2);

    let val = u16::from_le(unsafe { mem::transmute::<[u8;2], u16>(*data) });
    assert_eq!(val, t);
}

fn test_encode_u8() {
    let config = Config::new_empty();
    let mut buffer = Buffer::new();
    let value = Value::from(1 as u8);
    td_rp::encode_field(&mut buffer, &config, &value).unwrap();
    td_rp::encode_field(&mut buffer, &config, &value).unwrap();

    // first read field
    test_head_field(&mut buffer, 0, td_rp::TYPE_U8);
    // after index type is data
    let data: &mut [u8; 2] = &mut [0, 0];
    let size = buffer.read(data).unwrap();
    assert_eq!(size, 2);
    assert_eq!(data[0], 1);
    assert_eq!(data[1], 0);

    // second read field
    let read = td_rp::decode_field(&mut buffer, &config).unwrap();
    match read {
        Value::U8(val) => assert_eq!(val, 1),
        _ => unreachable!("it will not read"),
    }

    let size = buffer.read(data).unwrap();
    assert_eq!(size, 0);
}

字节是
[0, 0, 1, 0, 1] -- [0, 0]是id = 0,[1, 0]是type = 1是TYPE_U8,[1]是数据是1u8

示例proto

extern crate td_proto_rust;
use td_rp::{Value, Config, Buffer};

fn test_base_proto() {
    let config = td_rp::Config::new(" { \"name\" : { \"index\" :    1, \"pattern\" : \"string\" }, \
                                        \"index\" : { \"index\" :    2, \"pattern\" : \"u16\" },  \
                                        \"sub_name\" : { \"index\" :    3, \"pattern\" :\"string\" }   }",
        "{\"cmd_test_op\"        : { \"index\" :    1, \"args\" : [ \"map\" ] }}");
    let config = config.unwrap();
    let mut hash_value = HashMap::<String, Value>::new();
    hash_value.insert("name".to_string(), Value::from("I'm a chinese people".to_string()));
    hash_value.insert("sub_name".to_string(), Value::from("tickdream".to_string()));
    hash_value.insert("index".to_string(), Value::from(1 as u16));

    {
        let mut buffer = td_rp::encode_proto(&config, &"cmd_test_op".to_string(), vec![Value::from(hash_value.clone())]).unwrap();
        // just read field
        let read = td_rp::decode_proto(&mut buffer, &config).unwrap();
        match read {
            (name, val) => {
                assert_eq!(name, "cmd_test_op".to_string());
                assert_eq!(val[0], Value::from(hash_value));
            }
        }
    }
}

它将按照proto名称编码Vec,例如 "cmd_test_op" 定义的参数是 [map]

兼容性

它将确保解码数据的最大兼容性

  • 旧协议可以解码新协议,如果新协议没有改变旧字段信息,但会丢失一些信息
  • 新协议可以解码旧协议的所有数据

依赖项

~225KB