use {
crate::{
engine::Annotation,
value::types::{Type, TypeRef},
},
serde::{Deserialize, Serialize},
std::borrow::Borrow,
};
#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Hash)]
pub struct EndpointId(String);
impl AsRef<str> for EndpointId {
fn as_ref(&self) -> &str {
&self.0
}
}
impl Borrow<str> for EndpointId {
fn borrow(&self) -> &str {
&self.0
}
}
impl PartialEq<str> for EndpointId {
fn eq(&self, other: &str) -> bool {
self.0 == other
}
}
#[derive(Debug, Copy, Clone, Serialize, Deserialize, Eq, Hash, PartialEq)]
pub struct EndpointHandle(pub(crate) u32);
impl From<u32> for EndpointHandle {
fn from(handle: u32) -> Self {
Self(handle)
}
}
impl From<EndpointHandle> for u32 {
fn from(handle: EndpointHandle) -> Self {
handle.0
}
}
#[derive(Debug, Clone)]
pub enum EndpointInfo {
Stream(StreamEndpoint),
Event(EventEndpoint),
Value(ValueEndpoint),
}
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum EndpointDirection {
Input,
Output,
}
#[derive(Debug, Clone)]
pub struct StreamEndpoint {
id: EndpointId,
direction: EndpointDirection,
ty: Type,
annotation: Annotation,
}
impl From<StreamEndpoint> for EndpointInfo {
fn from(endpoint: StreamEndpoint) -> Self {
Self::Stream(endpoint)
}
}
#[derive(Debug, Clone)]
pub struct EventEndpoint {
id: EndpointId,
direction: EndpointDirection,
ty: Vec<Type>,
annotation: Annotation,
}
impl From<EventEndpoint> for EndpointInfo {
fn from(endpoint: EventEndpoint) -> Self {
Self::Event(endpoint)
}
}
#[derive(Debug, Clone)]
pub struct ValueEndpoint {
id: EndpointId,
direction: EndpointDirection,
ty: Type,
annotation: Annotation,
}
impl From<ValueEndpoint> for EndpointInfo {
fn from(endpoint: ValueEndpoint) -> Self {
Self::Value(endpoint)
}
}
impl EndpointInfo {
pub fn id(&self) -> &EndpointId {
match self {
Self::Stream(endpoint) => &endpoint.id,
Self::Event(endpoint) => &endpoint.id,
Self::Value(endpoint) => &endpoint.id,
}
}
pub fn direction(&self) -> EndpointDirection {
match self {
Self::Stream(endpoint) => endpoint.direction,
Self::Event(endpoint) => endpoint.direction,
Self::Value(endpoint) => endpoint.direction,
}
}
pub fn annotation(&self) -> &Annotation {
match self {
Self::Stream(endpoint) => &endpoint.annotation,
Self::Event(endpoint) => &endpoint.annotation,
Self::Value(endpoint) => &endpoint.annotation,
}
}
pub fn types(&self) -> &[Type] {
match self {
Self::Stream(endpoint) => std::slice::from_ref(&endpoint.ty),
Self::Event(endpoint) => &endpoint.ty,
Self::Value(endpoint) => std::slice::from_ref(&endpoint.ty),
}
}
pub fn as_stream(&self) -> Option<&StreamEndpoint> {
match self {
Self::Stream(endpoint) => Some(endpoint),
_ => None,
}
}
pub fn as_event(&self) -> Option<&EventEndpoint> {
match self {
Self::Event(endpoint) => Some(endpoint),
_ => None,
}
}
pub fn as_value(&self) -> Option<&ValueEndpoint> {
match self {
Self::Value(endpoint) => Some(endpoint),
_ => None,
}
}
}
impl ValueEndpoint {
pub(crate) fn new(
id: EndpointId,
direction: EndpointDirection,
ty: Type,
annotation: Annotation,
) -> Self {
Self {
id,
direction,
ty,
annotation,
}
}
pub fn id(&self) -> &EndpointId {
&self.id
}
pub fn direction(&self) -> EndpointDirection {
self.direction
}
pub fn ty(&self) -> &Type {
&self.ty
}
pub fn annotation(&self) -> &Annotation {
&self.annotation
}
}
impl StreamEndpoint {
pub(crate) fn new(
id: EndpointId,
direction: EndpointDirection,
ty: Type,
annotation: Annotation,
) -> Self {
Self {
id,
direction,
ty,
annotation,
}
}
pub fn id(&self) -> &EndpointId {
&self.id
}
pub fn direction(&self) -> EndpointDirection {
self.direction
}
pub fn ty(&self) -> &Type {
&self.ty
}
pub fn annotation(&self) -> &Annotation {
&self.annotation
}
}
impl EventEndpoint {
pub(crate) fn new(
id: EndpointId,
direction: EndpointDirection,
ty: Vec<Type>,
annotation: Annotation,
) -> Self {
assert!(!ty.is_empty());
Self {
id,
direction,
ty,
annotation,
}
}
pub fn id(&self) -> &EndpointId {
&self.id
}
pub fn direction(&self) -> EndpointDirection {
self.direction
}
pub fn types(&self) -> &[Type] {
&self.ty
}
pub fn annotation(&self) -> &Annotation {
&self.annotation
}
pub fn type_index(&self, ty: TypeRef<'_>) -> Option<EndpointTypeIndex> {
self.ty
.iter()
.position(|t| t.as_ref() == ty)
.map(EndpointTypeIndex::from)
}
pub fn get_type(&self, index: EndpointTypeIndex) -> Option<&Type> {
self.ty.get(usize::from(index))
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
pub struct EndpointTypeIndex(usize);
impl From<usize> for EndpointTypeIndex {
fn from(index: usize) -> Self {
Self(index)
}
}
impl From<EndpointTypeIndex> for usize {
fn from(index: EndpointTypeIndex) -> Self {
index.0
}
}