use alloc::string::ToString;
use core::fmt::Debug;
use decode::Decode;
use encode::Encode;
use geonetworking::NextAfterCommon;
#[cfg(feature = "json")]
use serde::{Deserialize, Serialize};
use crate::map_err_to_string;
pub(crate) mod decode;
pub(crate) mod encode;
#[derive(Debug, Clone, PartialEq)]
pub enum TransportHeader {
BtpA(BasicTransportAHeader),
BtpB(BasicTransportBHeader),
IPv6(alloc::boxed::Box<IPv6Header>),
}
impl TransportHeader {
pub fn decode_with_gn_next_header(
next_header: NextAfterCommon,
bytes: &[u8],
) -> Result<(&[u8], TransportHeader), alloc::string::String> {
match next_header {
NextAfterCommon::Any => {
Err("Currently, only BTP and IPv6 Headers can be decoded!".to_string())
}
NextAfterCommon::BTPA => BasicTransportAHeader::decode(bytes)
.map(|(rem, btpa)| (rem, TransportHeader::BtpA(btpa)))
.map_err(map_err_to_string),
NextAfterCommon::BTPB => BasicTransportBHeader::decode(bytes)
.map(|(rem, btpb)| (rem, TransportHeader::BtpB(btpb)))
.map_err(map_err_to_string),
NextAfterCommon::IPv6 => IPv6Header::decode(bytes)
.map(|(rem, ipv6)| (rem, TransportHeader::IPv6(alloc::boxed::Box::new(ipv6))))
.map_err(map_err_to_string),
}
}
pub fn encode(&self) -> Result<alloc::vec::Vec<u8>, alloc::string::String> {
match self {
TransportHeader::BtpA(a) => a.encode().map_err(map_err_to_string),
TransportHeader::BtpB(b) => b.encode().map_err(map_err_to_string),
TransportHeader::IPv6(_) => Err(alloc::string::String::from(
"Encoding IPv6 headers is unsupported!",
)),
}
}
#[cfg(feature = "json")]
pub fn encode_to_json(&self) -> Result<alloc::string::String, alloc::string::String> {
match self {
TransportHeader::BtpA(a) => a.encode_to_json().map_err(map_err_to_string),
TransportHeader::BtpB(b) => b.encode_to_json().map_err(map_err_to_string),
TransportHeader::IPv6(_) => Err(alloc::string::String::from(
"Encoding IPv6 headers is unsupported!",
)),
}
}
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct BasicTransportAHeader {
pub destination_port: u16,
pub source_port: u16,
}
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "json", derive(Serialize, Deserialize))]
pub struct BasicTransportBHeader {
pub destination_port: u16,
pub destination_port_info: u16,
}
#[derive(Debug, Clone, PartialEq)]
pub struct IPv6Header {
pub ip: Option<etherparse::NetHeaders>,
pub link: Option<etherparse::LinkHeader>,
pub transport: Option<etherparse::TransportHeader>,
pub link_ext: Option<etherparse::LinkExtHeader>,
}