1use std::collections::{BTreeSet, VecDeque};
15
16use crate::cap::CapId;
17use crate::error::{Error, Result};
18use crate::lane::LaneId;
19use crate::value::Value;
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
23pub struct ChannelId(pub u64);
24
25impl std::fmt::Display for ChannelId {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "ch{}", self.0)
28 }
29}
30
31#[derive(Debug, Clone, Copy, PartialEq, Eq)]
33pub enum Direction {
34 Send,
36 Receive,
38 Both,
40}
41
42impl Direction {
43 pub fn can_send(self) -> bool {
45 matches!(self, Direction::Send | Direction::Both)
46 }
47
48 pub fn can_receive(self) -> bool {
50 matches!(self, Direction::Receive | Direction::Both)
51 }
52}
53
54#[derive(Debug, Clone, PartialEq)]
56pub struct Message {
57 pub from: LaneId,
59 pub payload: Value,
61 pub caps: Vec<CapId>,
63 pub sequence: u64,
65}
66
67#[derive(Debug, Clone)]
69pub struct Channel {
70 pub id: ChannelId,
72 pub name: String,
74 pub direction: Direction,
76 queue: VecDeque<Message>,
77 next_sequence: u64,
78 closed: bool,
79 pub subscribers: BTreeSet<u64>,
81 pub sent: u64,
83 pub received: u64,
85}
86
87impl Channel {
88 pub fn new(id: ChannelId, name: impl Into<String>, direction: Direction) -> Self {
90 Self {
91 id,
92 name: name.into(),
93 direction,
94 queue: VecDeque::new(),
95 next_sequence: 0,
96 closed: false,
97 subscribers: BTreeSet::new(),
98 sent: 0,
99 received: 0,
100 }
101 }
102
103 pub fn can_send(&self) -> bool {
105 self.direction.can_send() && !self.closed
106 }
107
108 pub fn can_receive(&self) -> bool {
110 self.direction.can_receive() && !self.queue.is_empty()
111 }
112
113 pub fn send(&mut self, from: LaneId, payload: Value, caps: Vec<CapId>) -> Result<Message> {
115 if self.closed {
116 return Err(Error::InvalidArgument("channel is closed"));
117 }
118 if !self.direction.can_send() {
119 return Err(Error::InvalidArgument("channel is receive-only"));
120 }
121 let message = Message {
122 from,
123 payload,
124 caps,
125 sequence: self.next_sequence,
126 };
127 self.next_sequence += 1;
128 self.sent += 1;
129 self.queue.push_back(message.clone());
130 Ok(message)
131 }
132
133 pub fn recv(&mut self) -> Result<Option<Message>> {
135 if !self.direction.can_receive() {
136 return Err(Error::InvalidArgument("channel is send-only"));
137 }
138 match self.queue.pop_front() {
139 Some(message) => {
140 self.received += 1;
141 Ok(Some(message))
142 }
143 None => Ok(None),
144 }
145 }
146
147 pub fn peek(&self) -> Option<&Message> {
149 self.queue.front()
150 }
151
152 pub fn len(&self) -> usize {
155 self.queue.len()
156 }
157
158 pub fn is_empty(&self) -> bool {
160 self.queue.is_empty()
161 }
162
163 pub fn close(&mut self) {
165 self.closed = true;
166 }
167
168 pub fn is_closed(&self) -> bool {
170 self.closed
171 }
172}