use bytes::{BufMut, Bytes, BytesMut};
use core::ops::{Deref, DerefMut};
use rseip_core::String;
use smallvec::{smallvec, SmallVec};
pub const EPATH_CONNECTION_MANAGER: &[u8] = &[0x20, 0x06, 0x24, 0x01];
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Segment {
Symbol(String),
Class(u16),
Instance(u16),
Attribute(u16),
Element(u32),
Port(PortSegment),
}
impl Segment {
#[inline]
pub fn is_port(&self) -> bool {
match self {
Self::Port(_) => true,
_ => false,
}
}
}
type Array = [Segment; 4];
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct EPath(SmallVec<Array>);
impl EPath {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn into_inner(self) -> SmallVec<Array> {
self.0
}
#[inline]
pub fn with_class(mut self, class_id: u16) -> Self {
self.0.push(Segment::Class(class_id));
self
}
#[inline]
pub fn with_symbol(mut self, symbol: impl Into<String>) -> Self {
self.0.push(Segment::Symbol(symbol.into()));
self
}
#[inline]
pub fn with_instance(mut self, instance_id: u16) -> Self {
self.0.push(Segment::Instance(instance_id));
self
}
#[inline]
pub fn with_element(mut self, element_idx: u32) -> Self {
self.0.push(Segment::Element(element_idx));
self
}
#[inline]
pub fn with_port(mut self, port: u16) -> Self {
self.0.push(Segment::Port(PortSegment {
port,
link: Bytes::from_static(&[0]),
}));
self
}
#[inline]
pub fn with_port_slot(mut self, port: u16, slot: u8) -> Self {
let mut buf = BytesMut::new();
buf.put_u8(slot);
self.0.push(Segment::Port(PortSegment {
port,
link: buf.freeze(),
}));
self
}
#[inline]
pub fn from_symbol(symbol: impl Into<String>) -> Self {
EPath(smallvec![Segment::Symbol(symbol.into())])
}
#[inline]
pub fn insert(&mut self, index: usize, item: Segment) {
self.0.insert(index, item)
}
#[inline]
pub fn push(&mut self, item: Segment) {
self.0.push(item);
}
#[inline]
pub fn remove(&mut self, index: usize) {
self.0.remove(index);
}
}
impl IntoIterator for EPath {
type Item = Segment;
type IntoIter = rseip_core::iter::IntoIter<Array>;
fn into_iter(self) -> Self::IntoIter {
rseip_core::iter::IntoIter::new(self.0)
}
}
impl Deref for EPath {
type Target = [Segment];
#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for EPath {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl From<Vec<Segment>> for EPath {
#[inline]
fn from(src: Vec<Segment>) -> Self {
Self(SmallVec::from_vec(src))
}
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PortSegment {
pub port: u16,
pub link: Bytes,
}
impl Default for PortSegment {
#[inline]
fn default() -> Self {
Self {
port: 1, link: Bytes::from_static(&[0]), }
}
}