koibumi-core 0.0.9

The core library for Koibumi, an experimental Bitmessage client
Documentation
//! Message types defined in the Bitmessage protocol.

mod error;
pub use crate::message::error::{Error, ErrorText, Fatal};

mod getdata;
pub use crate::message::getdata::Getdata;

mod inv;
pub use crate::message::inv::Inv;

// TODO Dinv
//mod dinv;
//pub use crate::message::dinv::Dinv;

mod object;
pub use crate::message::object::Object;

mod addr;
pub use crate::message::addr::Addr;

// TODO Portcheck
//mod portcheck;
//pub use crate::message::portcheck::Portcheck;

mod ping;
pub use crate::message::ping::Ping;

mod pong;
pub use crate::message::pong::Pong;

mod verack;
pub use crate::message::verack::Verack;

mod version;
pub use crate::message::version::{NodeNonce, ProtocolVersion, UserAgent, Version};

use std::{
    fmt,
    io::{self, Read, Write},
};

use crate::{
    config::Config,
    io::{ReadFrom, WriteTo},
    packet::{self, Command, Packet},
    priv_util::ToHexString,
};

pub use crate::{
    io::TooLongError,
    net_addr::{NetAddr, Services},
    stream::{StreamNumber, StreamNumbers},
};

/// Indicates that this object is a Bitmessage message
/// and informs what type of message it is.
pub trait Message {
    /// What type of message this is.
    const COMMAND: Command;
}

/// Provides a method that creates a Bitmessage packet from the Bitmessage message.
pub trait Pack {
    /// Returns a Bitmessage packet created from the Bitmessage message.
    fn pack(&self, config: &Config) -> packet::Result<Packet>;
}

impl<T> Pack for T
where
    T: WriteTo + Message,
{
    fn pack(&self, config: &Config) -> packet::Result<Packet> {
        let mut bytes = Vec::new();
        self.write_to(&mut bytes).unwrap();
        Packet::new(config, Self::COMMAND, bytes)
    }
}

/// A hash value of an object message, used to specify the object message.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct InvHash([u8; 32]);

impl InvHash {
    /// Constructs an inventory hash from a byte array.
    pub fn new(value: [u8; 32]) -> Self {
        Self(value)
    }
}

impl fmt::Display for InvHash {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        self.0.to_hex_string().fmt(f)
    }
}

impl AsRef<[u8]> for InvHash {
    fn as_ref(&self) -> &[u8] {
        &self.0
    }
}

impl WriteTo for InvHash {
    fn write_to(&self, w: &mut dyn Write) -> io::Result<()> {
        self.0.write_to(w)
    }
}

impl ReadFrom for InvHash {
    fn read_from(r: &mut dyn Read) -> io::Result<Self>
    where
        Self: Sized,
    {
        Ok(Self(<[u8; 32]>::read_from(r)?))
    }
}