Skip to main content

chrome_for_testing_manager/
port.rs

1use std::fmt::{Display, Formatter};
2
3/// A TCP port bound (or to be bound) by a chromedriver process.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct Port(u16);
6
7impl Port {
8    /// Create a typed port from a raw `u16`.
9    #[must_use]
10    pub const fn new(value: u16) -> Self {
11        Self(value)
12    }
13
14    /// Return the raw `u16` port value.
15    #[must_use]
16    pub const fn as_u16(self) -> u16 {
17        self.0
18    }
19}
20
21impl From<u16> for Port {
22    fn from(value: u16) -> Self {
23        Self::new(value)
24    }
25}
26
27impl AsRef<u16> for Port {
28    fn as_ref(&self) -> &u16 {
29        &self.0
30    }
31}
32
33impl Display for Port {
34    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35        self.0.fmt(f)
36    }
37}
38
39/// How chromedriver should pick the port it listens on.
40#[derive(Debug, Clone, Copy, PartialEq, Eq)]
41pub enum PortRequest {
42    /// Let the OS assign an unused port.
43    Any,
44
45    /// Bind to a specific port.
46    Specific(Port),
47}
48
49impl From<u16> for PortRequest {
50    fn from(value: u16) -> Self {
51        Self::Specific(Port::new(value))
52    }
53}
54
55impl From<Port> for PortRequest {
56    fn from(value: Port) -> Self {
57        Self::Specific(value)
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use super::*;
64    use assertr::prelude::*;
65
66    #[test]
67    fn port_from_u16_constructs_typed_port() {
68        assert_that!(Port::from(8080u16)).is_equal_to(Port::new(8080));
69        assert_that!(Port::from(8080u16).as_u16()).is_equal_to(8080);
70    }
71
72    #[test]
73    fn port_request_from_u16_constructs_specific_port() {
74        assert_that!(PortRequest::from(8080u16))
75            .is_equal_to(PortRequest::Specific(Port::new(8080)));
76    }
77}