1#![deny(missing_debug_implementations)]
10use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
13
14pub mod ffi;
15
16pub mod agent;
17pub mod candidate;
18pub mod component;
19pub mod stream;
20
21pub mod prelude {
23 pub use crate::candidate::CandidateApi;
24}
25
26pub struct Address {
28 ffi: *mut crate::ffi::RiceAddress,
29}
30
31unsafe impl Send for Address {}
32unsafe impl Sync for Address {}
33
34impl core::fmt::Debug for Address {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 if self.ffi.is_null() {
37 f.debug_struct("Address").field("ffi", &self.ffi).finish()
38 } else {
39 f.debug_struct("Address")
40 .field("ffi", &self.ffi)
41 .field("value", &self.as_socket())
42 .finish()
43 }
44 }
45}
46
47impl Clone for Address {
48 fn clone(&self) -> Self {
49 Self {
50 ffi: unsafe { crate::ffi::rice_address_copy(self.ffi) },
51 }
52 }
53}
54
55impl Drop for Address {
56 fn drop(&mut self) {
57 unsafe { crate::ffi::rice_address_free(self.ffi) }
58 }
59}
60
61impl Address {
62 pub(crate) fn as_c(&self) -> *mut crate::ffi::RiceAddress {
63 self.ffi
64 }
65
66 pub(crate) fn into_c_full(self) -> *mut crate::ffi::RiceAddress {
67 let ret = self.ffi;
68 core::mem::forget(self);
69 ret
70 }
71
72 pub(crate) fn from_c_none(ffi: *const crate::ffi::RiceAddress) -> Self {
73 Self {
74 ffi: unsafe { crate::ffi::rice_address_copy(ffi) },
75 }
76 }
77
78 pub(crate) fn from_c_full(ffi: *mut crate::ffi::RiceAddress) -> Self {
79 Self { ffi }
80 }
81
82 pub fn as_socket(&self) -> SocketAddr {
84 self.into()
85 }
86}
87
88impl From<SocketAddr> for Address {
89 fn from(addr: SocketAddr) -> Self {
90 match addr.ip() {
91 IpAddr::V4(v4) => Self {
92 ffi: unsafe {
93 crate::ffi::rice_address_new_from_bytes(
94 crate::ffi::RICE_ADDRESS_FAMILY_IPV4,
95 v4.octets().as_ptr(),
96 addr.port(),
97 )
98 },
99 },
100 IpAddr::V6(v6) => Self {
101 ffi: unsafe {
102 crate::ffi::rice_address_new_from_bytes(
103 crate::ffi::RICE_ADDRESS_FAMILY_IPV6,
104 v6.octets().as_ptr(),
105 addr.port(),
106 )
107 },
108 },
109 }
110 }
111}
112
113impl From<&Address> for SocketAddr {
114 fn from(value: &Address) -> Self {
115 unsafe {
116 let port = crate::ffi::rice_address_get_port(value.ffi);
117 let ip = match crate::ffi::rice_address_get_family(value.ffi) {
118 crate::ffi::RICE_ADDRESS_FAMILY_IPV4 => {
119 let mut octets = [0; 4];
120 crate::ffi::rice_address_get_address_bytes(value.ffi, octets.as_mut_ptr());
121 IpAddr::V4(Ipv4Addr::from(octets))
122 }
123 crate::ffi::RICE_ADDRESS_FAMILY_IPV6 => {
124 let mut octets = [0; 16];
125 crate::ffi::rice_address_get_address_bytes(value.ffi, octets.as_mut_ptr());
126 IpAddr::V6(Ipv6Addr::from(octets))
127 }
128 val => panic!("Unknown address family value {val:x?}"),
129 };
130 SocketAddr::new(ip, port)
131 }
132 }
133}
134
135impl std::str::FromStr for Address {
136 type Err = std::net::AddrParseError;
137
138 fn from_str(s: &str) -> Result<Self, Self::Err> {
139 let addr: SocketAddr = s.parse()?;
140 Ok(Self::from(addr))
141 }
142}
143
144impl PartialEq<Address> for Address {
145 fn eq(&self, other: &Address) -> bool {
146 unsafe { crate::ffi::rice_address_cmp(self.ffi, other.ffi) == 0 }
147 }
148}
149
150fn mut_override<T>(val: *const T) -> *mut T {
151 val as *mut T
152}
153
154fn const_override<T>(val: *mut T) -> *const T {
155 val as *const T
156}
157
158#[cfg(test)]
159pub(crate) mod tests {
160 use tracing::subscriber::DefaultGuard;
161 use tracing_subscriber::layer::SubscriberExt;
162 use tracing_subscriber::Layer;
163
164 use super::*;
165
166 pub fn test_init_log() -> DefaultGuard {
167 let level_filter = std::env::var("RICE_LOG")
168 .or(std::env::var("RUST_LOG"))
169 .ok()
170 .and_then(|var| var.parse::<tracing_subscriber::filter::Targets>().ok())
171 .unwrap_or(
172 tracing_subscriber::filter::Targets::new().with_default(tracing::Level::TRACE),
173 );
174 let registry = tracing_subscriber::registry().with(
175 tracing_subscriber::fmt::layer()
176 .with_file(true)
177 .with_line_number(true)
178 .with_level(true)
179 .with_target(false)
180 .with_test_writer()
181 .with_filter(level_filter),
182 );
183 tracing::subscriber::set_default(registry)
184 }
185}