nell 0.3.0

Linux netlink interface
Documentation
// Copyright (C) 2020 - Will Glozer. All rights reserved.

use std::convert::TryFrom;
use anyhow::Result;
use crate::api::IFLA;
use crate::ffi::*;
use crate::sys::{Cursor, Netlink, reader};
use super::{attr, Buffer, message, write};

#[test]
fn write_attr() -> Result<()> {
    let mut buf = [0u8; 64];
    let mut buf = Buffer::new(&mut buf);

    let addr  = &[1, 2, 3, 4][..];
    let attrs = &[
        attr(IFLA_ADDRESS, addr),
        attr(IFLA_MTU,     1500u32),
        attr(IFLA_IFNAME,  "test"),
    ];

    for attr in attrs {
        attr.write(&mut buf)?;
    }

    let mut tail = Cursor::from(buf.bytes());
    let mut next = || tail.next().map(IFLA::try_from);

    assert_eq!(IFLA::Address(addr),  next().unwrap()?);
    assert_eq!(IFLA::MTU(1500),      next().unwrap()?);
    assert_eq!(IFLA::IFName("test"), next().unwrap()?);

    Ok(())
}

#[test]
fn write_message() -> Result<()> {
    let mut buf = [0u8; 64];

    let addr = &[1, 2, 3, 4][..];
    let name = "test".to_owned();

    let data = ifinfomsg {
        ifi_family: AF_INET,
        ifi_index:  1,
        ..Default::default()
    };

    let msg = message(RTM_NEWLINK, data.clone(), &[
        attr(IFLA_ADDRESS, addr),
        attr(IFLA_MTU,     1500u32),
        attr(IFLA_IFNAME,  &*name),
    ]).build(&mut buf)?;

    let mut buf = [0u8; 64];
    let message = write(&mut buf, &msg)?;

    let mut cursor = Cursor::from(message);
    let msg = match reader::next::<ifinfomsg>(&mut cursor) {
        Some(Ok(Netlink::Msg(msg))) => msg,
        other                       => panic!("unexpected {:?}", other),
    };

    let (head, data, mut tail) = msg.parts();

    assert_eq!(RTM_NEWLINK, head.nlmsg_type);
    assert_eq!(data, data);

    let mut next = || tail.next().map(IFLA::try_from);

    assert_eq!(IFLA::Address(addr),  next().unwrap()?);
    assert_eq!(IFLA::MTU(1500),      next().unwrap()?);
    assert_eq!(IFLA::IFName("test"), next().unwrap()?);

    Ok(())
}