dope_core/io/socket/addr/
inet.rs1use std::{
2 cell, marker, net,
3 os::{fd, fd::AsFd as _},
4};
5
6use dope_sys::{
7 Errno,
8 io::socket::{BACKLOG, Kind, Socket as _, addr},
9};
10
11use crate::{
12 Backend,
13 io::socket::{Addr, BindError, Prepared, StreamSpec, addr::prepared},
14};
15
16#[derive(Clone, Copy)]
17pub struct Inet {
18 native: addr::Internet,
19}
20
21#[must_use]
23pub struct Listener {
24 fd: fd::OwnedFd,
25 local_addr: net::SocketAddr,
26 thread: marker::PhantomData<cell::Cell<()>>,
27}
28
29impl Listener {
30 pub fn bind(addr: net::SocketAddr) -> Result<Self, BindError> {
32 let address = Inet::from_std(addr);
33 let domain = address.stream_spec().domain().raw();
34 let fd = Backend::socket(domain, Kind::Stream.raw()).map_err(BindError::socket)?;
35 let borrowed = fd.as_fd();
36 address
37 .view()
38 .native()
39 .try_bind::<Backend, Errno>(borrowed)
40 .map_err(BindError::Bind)?;
41 Backend::listen::<Errno>(borrowed, BACKLOG).map_err(BindError::Listen)?;
42 let local = Addr::local(borrowed)
43 .map_err(BindError::LocalAddress)?
44 .into_std()
45 .map_err(BindError::Address)?;
46 Ok(Self {
47 fd,
48 local_addr: local,
49 thread: marker::PhantomData,
50 })
51 }
52
53 pub const fn local_addr(&self) -> net::SocketAddr {
54 self.local_addr
55 }
56
57 pub(in crate::io::socket) fn into_parts(self) -> (fd::OwnedFd, net::SocketAddr) {
58 (self.fd, self.local_addr)
59 }
60}
61
62impl Inet {
63 pub fn from_std(address: net::SocketAddr) -> Self {
64 Self {
65 native: addr::Internet::from_std::<Backend>(address),
66 }
67 }
68}
69
70impl From<&net::SocketAddr> for Inet {
71 fn from(address: &net::SocketAddr) -> Self {
72 Self::from_std(*address)
73 }
74}
75
76impl prepared::Sealed for Inet {}
77
78impl Prepared for Inet {
79 fn view(&self) -> prepared::View<'_> {
80 prepared::View(self.native.as_addr())
81 }
82
83 fn stream_spec(&self) -> StreamSpec {
84 StreamSpec(self.native.domain())
85 }
86}
87
88const _: () = assert!(size_of::<Inet>() <= 32);
89
90impl Inet {
91 pub fn try_connect(&self, fd: fd::BorrowedFd<'_>) -> Result<(), crate::Errno> {
93 self.view().native().try_connect::<Backend, Errno>(fd)
94 }
95}