1use crate::error::Reason;
2use crate::frame::{Pseudo, StreamId};
3use crate::proto::{Error, Open};
4
5use http::{HeaderMap, Request, Response};
6
7use std::fmt;
8
9pub(crate) trait Peer {
11 type Poll: fmt::Debug;
13 const NAME: &'static str;
14
15 fn r#dyn() -> Dyn;
16
17 fn convert_poll_message(
20 pseudo: Pseudo,
21 fields: HeaderMap,
22 stream_id: StreamId,
23 ) -> Result<Self::Poll, Error>;
24
25 }
32
33#[derive(Debug, Copy, Clone, Eq, PartialEq)]
37pub(crate) enum Dyn {
38 Client,
39 Server,
40}
41
42#[derive(Debug)]
43pub enum PollMessage {
44 Client(Response<()>),
45 Server(Request<()>),
46}
47
48impl Dyn {
51 pub fn is_server(&self) -> bool {
52 *self == Dyn::Server
53 }
54
55 pub fn is_local_init(&self, id: StreamId) -> bool {
56 assert!(!id.is_zero());
57 self.is_server() == id.is_server_initiated()
58 }
59
60 pub fn convert_poll_message(
61 &self,
62 pseudo: Pseudo,
63 fields: HeaderMap,
64 stream_id: StreamId,
65 ) -> Result<PollMessage, Error> {
66 if self.is_server() {
67 crate::server::Peer::convert_poll_message(pseudo, fields, stream_id)
68 .map(PollMessage::Server)
69 } else {
70 crate::client::Peer::convert_poll_message(pseudo, fields, stream_id)
71 .map(PollMessage::Client)
72 }
73 }
74
75 pub fn ensure_can_open(&self, id: StreamId, mode: Open) -> Result<(), Error> {
77 if self.is_server() {
78 if mode.is_push_promise() || !id.is_client_initiated() {
80 proto_err!(conn: "cannot open stream {:?} - not client initiated", id);
81 return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
82 }
83
84 Ok(())
85 } else {
86 if !mode.is_push_promise() || !id.is_server_initiated() {
88 proto_err!(conn: "cannot open stream {:?} - not server initiated", id);
89 return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
90 }
91
92 Ok(())
93 }
94 }
95}