Skip to main content

pharos_runtime_core/
connection.rs

1use std::io::{Read, Write};
2use std::net::{Shutdown, TcpListener, TcpStream};
3#[cfg(unix)]
4use std::os::unix::net::UnixStream;
5
6#[derive(Debug, Clone, Copy, Eq, PartialEq)]
7/// Transport families supported by the native connection wrapper.
8///
9/// # Variants
10///
11/// - `Unknown`: Supported `NativeTransportType` variant.
12/// - `Tcp`: Supported `NativeTransportType` variant.
13/// - `Unix`: Supported `NativeTransportType` variant.
14///
15/// # Examples
16///
17/// ```rust,ignore
18/// let _ = pharos_runtime_core::connection::NativeTransportType::Unknown;
19/// ```
20///
21/// # Related
22///
23/// - [`crate::connection`] for constructors, helpers, and neighboring runtime types.
24pub enum NativeTransportType {
25    Unknown,
26    Tcp,
27    Unix,
28}
29
30enum NativeConnectionStream {
31    Tcp(TcpStream),
32    #[cfg(unix)]
33    Unix(UnixStream),
34}
35
36/// Native connection wrapper used by the runtime for TCP and Unix transports.
37///
38/// # Fields
39///
40/// - `fd`: Stored field on `NativeConnection`.
41/// - `write_fd`: Stored field on `NativeConnection`.
42/// - `close_fds`: Stored field on `NativeConnection`.
43/// - `transport_type`: Stored field on `NativeConnection`.
44/// - `peer_info`: Stored field on `NativeConnection`.
45/// - `local_info`: Stored field on `NativeConnection`.
46///
47/// # Examples
48///
49/// ```rust,ignore
50/// let _ = std::mem::size_of::<pharos_runtime_core::connection::NativeConnection>();
51/// ```
52///
53/// # Related
54///
55/// - [`crate::connection`] for constructors, helpers, and neighboring runtime types.
56pub struct NativeConnection {
57    pub fd: i32,
58    pub write_fd: i32,
59    pub close_fds: bool,
60    pub transport_type: NativeTransportType,
61    pub peer_info: Option<String>,
62    pub local_info: Option<String>,
63    stream: Option<NativeConnectionStream>,
64}
65
66impl NativeConnection {
67    /// Performs metadata only.
68    ///
69    /// # Parameters
70    ///
71    /// - `transport_type`: Input consumed by [`crate::connection::metadata_only`].
72    /// - `peer_info`: Input consumed by [`crate::connection::metadata_only`].
73    /// - `local_info`: Input consumed by [`crate::connection::metadata_only`].
74    ///
75    /// # Returns
76    ///
77    /// Returns the computed value produced by [`crate::connection::metadata_only`].
78    ///
79    /// # Examples
80    ///
81    /// ```rust,ignore
82    /// let _result = pharos_runtime_core::connection::metadata_only(todo!(), todo!(), todo!());
83    /// ```
84    ///
85    /// # Related
86    ///
87    /// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
88    pub fn metadata_only(
89        transport_type: NativeTransportType,
90        peer_info: Option<String>,
91        local_info: Option<String>,
92    ) -> Self {
93        Self {
94            fd: -1,
95            write_fd: -1,
96            close_fds: true,
97            transport_type,
98            peer_info,
99            local_info,
100            stream: None,
101        }
102    }
103
104    /// Performs from TCP stream.
105    ///
106    /// # Parameters
107    ///
108    /// - `stream`: Input consumed by [`crate::connection::from_tcp_stream`].
109    ///
110    /// # Returns
111    ///
112    /// Returns the computed value produced by [`crate::connection::from_tcp_stream`].
113    ///
114    /// # Examples
115    ///
116    /// ```rust,ignore
117    /// let _result = pharos_runtime_core::connection::from_tcp_stream(todo!());
118    /// ```
119    ///
120    /// # Related
121    ///
122    /// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
123    pub fn from_tcp_stream(stream: TcpStream) -> Self {
124        let peer_info = stream.peer_addr().ok().map(|value| value.to_string());
125        let local_info = stream.local_addr().ok().map(|value| value.to_string());
126        Self {
127            fd: 0,
128            write_fd: 0,
129            close_fds: true,
130            transport_type: NativeTransportType::Tcp,
131            peer_info,
132            local_info,
133            stream: Some(NativeConnectionStream::Tcp(stream)),
134        }
135    }
136
137    #[cfg(unix)]
138    /// Wraps a Unix-domain stream in a [`NativeConnection`].
139    ///
140    /// # Parameters
141    ///
142    /// - `stream`: Input consumed by [`crate::connection::from_unix_stream`].
143    ///
144    /// # Returns
145    ///
146    /// Returns the computed value produced by [`crate::connection::from_unix_stream`].
147    ///
148    /// # Examples
149    ///
150    /// ```rust,ignore
151    /// let _result = pharos_runtime_core::connection::from_unix_stream(todo!());
152    /// ```
153    ///
154    /// # Related
155    ///
156    /// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
157    pub fn from_unix_stream(stream: UnixStream) -> Self {
158        let peer_info = Some(
159            stream
160                .peer_addr()
161                .ok()
162                .and_then(|value| {
163                    value
164                        .as_pathname()
165                        .map(|path| path.to_string_lossy().into_owned())
166                })
167                .unwrap_or_else(|| "unix".to_owned()),
168        );
169        let local_info = Some(
170            stream
171                .local_addr()
172                .ok()
173                .and_then(|value| {
174                    value
175                        .as_pathname()
176                        .map(|path| path.to_string_lossy().into_owned())
177                })
178                .unwrap_or_else(|| "unix".to_owned()),
179        );
180        Self {
181            fd: 0,
182            write_fd: 0,
183            close_fds: true,
184            transport_type: NativeTransportType::Unix,
185            peer_info,
186            local_info,
187            stream: Some(NativeConnectionStream::Unix(stream)),
188        }
189    }
190}
191
192/// Initializes a metadata-only connection before a transport is attached.
193///
194/// # Parameters
195///
196/// - `transport_type`: Input consumed by [`crate::connection::connection_init`].
197/// - `peer_info`: Input consumed by [`crate::connection::connection_init`].
198/// - `local_info`: Input consumed by [`crate::connection::connection_init`].
199///
200/// # Returns
201///
202/// Returns the computed value produced by [`crate::connection::connection_init`].
203///
204/// # Examples
205///
206/// ```rust,ignore
207/// let _result = pharos_runtime_core::connection::connection_init(todo!(), todo!(), todo!());
208/// ```
209///
210/// # Related
211///
212/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
213pub fn connection_init(
214    transport_type: NativeTransportType,
215    peer_info: Option<String>,
216    local_info: Option<String>,
217) -> NativeConnection {
218    NativeConnection::metadata_only(transport_type, peer_info, local_info)
219}
220
221/// Performs connection flush.
222///
223/// # Parameters
224///
225/// - `connection`: Input consumed by [`crate::connection::connection_flush`].
226///
227/// # Returns
228///
229/// Returns the computed value produced by [`crate::connection::connection_flush`].
230///
231/// # Examples
232///
233/// ```rust,ignore
234/// let _result = pharos_runtime_core::connection::connection_flush(todo!());
235/// ```
236///
237/// # Related
238///
239/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
240pub fn connection_flush(connection: &mut NativeConnection) -> i32 {
241    match connection.stream.as_mut() {
242        Some(NativeConnectionStream::Tcp(stream)) => stream.flush().map(|_| 0).unwrap_or(69),
243        #[cfg(unix)]
244        Some(NativeConnectionStream::Unix(stream)) => stream.flush().map(|_| 0).unwrap_or(69),
245        None => 0,
246    }
247}
248
249/// Formats endpoint text without exposing platform socket handles or FFI state.
250///
251/// # Parameters
252///
253/// - `endpoint`: Input consumed by [`crate::connection::connection_format_sockaddr`].
254///
255/// # Returns
256///
257/// Returns the computed value produced by [`crate::connection::connection_format_sockaddr`].
258///
259/// # Examples
260///
261/// ```rust,ignore
262/// let _result = pharos_runtime_core::connection::connection_format_sockaddr("127.0.0.1:8080");
263/// ```
264///
265/// # Related
266///
267/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
268pub fn connection_format_sockaddr(endpoint: Option<&str>) -> String {
269    endpoint
270        .map(str::trim)
271        .filter(|value| !value.is_empty())
272        .unwrap_or("unknown")
273        .to_owned()
274}
275
276/// Reads at most one caller-provided buffer from the attached transport.
277///
278/// # Parameters
279///
280/// - `connection`: Input consumed by [`crate::connection::connection_read`].
281/// - `buffer`: Input consumed by [`crate::connection::connection_read`].
282///
283/// # Returns
284///
285/// Returns the computed value produced by [`crate::connection::connection_read`].
286///
287/// # Examples
288///
289/// ```rust,ignore
290/// let _result = pharos_runtime_core::connection::connection_read(todo!(), &mut []);
291/// ```
292///
293/// # Related
294///
295/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
296pub fn connection_read(connection: &mut NativeConnection, buffer: &mut [u8]) -> i32 {
297    if buffer.is_empty() {
298        return 0;
299    }
300    match connection.stream.as_mut() {
301        Some(NativeConnectionStream::Tcp(stream)) => {
302            stream.read(buffer).map(|count| count as i32).unwrap_or(-1)
303        }
304        #[cfg(unix)]
305        Some(NativeConnectionStream::Unix(stream)) => {
306            stream.read(buffer).map(|count| count as i32).unwrap_or(-1)
307        }
308        None => -1,
309    }
310}
311
312/// Writes one complete caller-provided buffer to the attached transport.
313///
314/// # Parameters
315///
316/// - `connection`: Input consumed by [`crate::connection::connection_write`].
317/// - `buffer`: Input consumed by [`crate::connection::connection_write`].
318///
319/// # Returns
320///
321/// Returns the computed value produced by [`crate::connection::connection_write`].
322///
323/// # Examples
324///
325/// ```rust,ignore
326/// let _result = pharos_runtime_core::connection::connection_write(todo!(), &mut []);
327/// ```
328///
329/// # Related
330///
331/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
332pub fn connection_write(connection: &mut NativeConnection, buffer: &[u8]) -> i32 {
333    if buffer.is_empty() {
334        return 0;
335    }
336    match connection.stream.as_mut() {
337        Some(NativeConnectionStream::Tcp(stream)) => {
338            stream.write(buffer).map(|count| count as i32).unwrap_or(-1)
339        }
340        #[cfg(unix)]
341        Some(NativeConnectionStream::Unix(stream)) => {
342            stream.write(buffer).map(|count| count as i32).unwrap_or(-1)
343        }
344        None => -1,
345    }
346}
347
348/// Accepts the next TCP connection from a native listener.
349///
350/// # Parameters
351///
352/// - `listener`: Input consumed by [`crate::connection::connection_accept_next`].
353///
354/// # Returns
355///
356/// Returns the successful value produced by [`crate::connection::connection_accept_next`] or an error when the operation fails.
357///
358/// # Errors
359///
360/// Returns an error value when [`crate::connection::connection_accept_next`] cannot complete successfully.
361///
362/// # Examples
363///
364/// ```rust,ignore
365/// let _result = pharos_runtime_core::connection::connection_accept_next(todo!());
366/// ```
367///
368/// # Related
369///
370/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
371pub fn connection_accept_next(listener: &TcpListener) -> Result<NativeConnection, i32> {
372    listener
373        .accept()
374        .map(|(stream, _)| NativeConnection::from_tcp_stream(stream))
375        .map_err(|_| 71)
376}
377
378/// Closes one connection and clears its owned stream.
379///
380/// # Parameters
381///
382/// - `connection`: Input consumed by [`crate::connection::connection_close`].
383///
384/// # Returns
385///
386/// Returns the computed value produced by [`crate::connection::connection_close`].
387///
388/// # Examples
389///
390/// ```rust,ignore
391/// let _result = pharos_runtime_core::connection::connection_close(todo!());
392/// ```
393///
394/// # Related
395///
396/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
397pub fn connection_close(connection: &mut NativeConnection) -> i32 {
398    let status = connection_shutdown(connection);
399    connection.stream = None;
400    connection.fd = -1;
401    connection.write_fd = -1;
402    status
403}
404
405/// Applies bounded read and write timeouts to a native connection.
406///
407/// # Parameters
408///
409/// - `connection`: Input consumed by [`crate::connection::connection_apply_timeouts`].
410/// - `read_ms`: Input consumed by [`crate::connection::connection_apply_timeouts`].
411/// - `write_ms`: Input consumed by [`crate::connection::connection_apply_timeouts`].
412///
413/// # Returns
414///
415/// Returns the computed value produced by [`crate::connection::connection_apply_timeouts`].
416///
417/// # Examples
418///
419/// ```rust,ignore
420/// let _result = pharos_runtime_core::connection::connection_apply_timeouts(todo!(), todo!(), todo!());
421/// ```
422///
423/// # Related
424///
425/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
426pub fn connection_apply_timeouts(
427    connection: &mut NativeConnection,
428    read_ms: Option<u64>,
429    write_ms: Option<u64>,
430) -> i32 {
431    let result = match connection.stream.as_mut() {
432        Some(NativeConnectionStream::Tcp(stream)) => {
433            let read = read_ms
434                .map(std::time::Duration::from_millis)
435                .map(|value| stream.set_read_timeout(Some(value)));
436            let write = write_ms
437                .map(std::time::Duration::from_millis)
438                .map(|value| stream.set_write_timeout(Some(value)));
439            read.into_iter().chain(write).all(|result| result.is_ok())
440        }
441        #[cfg(unix)]
442        Some(NativeConnectionStream::Unix(stream)) => {
443            let read = read_ms
444                .map(std::time::Duration::from_millis)
445                .map(|value| stream.set_read_timeout(Some(value)));
446            let write = write_ms
447                .map(std::time::Duration::from_millis)
448                .map(|value| stream.set_write_timeout(Some(value)));
449            read.into_iter().chain(write).all(|result| result.is_ok())
450        }
451        None => true,
452    };
453    i32::from(!result)
454}
455
456/// Closes the underlying socket transport.
457///
458/// # Parameters
459///
460/// - `connection`: Input consumed by [`crate::connection::connection_close_socket`].
461///
462/// # Returns
463///
464/// Returns the computed value produced by [`crate::connection::connection_close_socket`].
465///
466/// # Examples
467///
468/// ```rust,ignore
469/// let _result = pharos_runtime_core::connection::connection_close_socket(todo!());
470/// ```
471///
472/// # Related
473///
474/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
475pub fn connection_close_socket(connection: &mut NativeConnection) -> i32 {
476    connection_close(connection)
477}
478
479/// Shuts down both directions of the attached socket and preserves close semantics.
480///
481/// # Parameters
482///
483/// - `connection`: Input consumed by [`crate::connection::connection_shutdown_socket`].
484///
485/// # Returns
486///
487/// Returns the computed value produced by [`crate::connection::connection_shutdown_socket`].
488///
489/// # Examples
490///
491/// ```rust,ignore
492/// let _result = pharos_runtime_core::connection::connection_shutdown_socket(todo!());
493/// ```
494///
495/// # Related
496///
497/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
498pub fn connection_shutdown_socket(connection: &mut NativeConnection) -> i32 {
499    connection_shutdown(connection)
500}
501
502/// Returns the transport kind currently attached to a connection.
503///
504/// # Parameters
505///
506/// - `connection`: Input consumed by [`crate::connection::connection_detect_transport`].
507///
508/// # Returns
509///
510/// Returns the computed value produced by [`crate::connection::connection_detect_transport`].
511///
512/// # Examples
513///
514/// ```rust,ignore
515/// let _result = pharos_runtime_core::connection::connection_detect_transport(todo!());
516/// ```
517///
518/// # Related
519///
520/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
521pub fn connection_detect_transport(connection: &NativeConnection) -> NativeTransportType {
522    connection.transport_type
523}
524
525/// Refreshes peer and local endpoint metadata from the attached stream.
526///
527/// # Parameters
528///
529/// - `connection`: Input consumed by [`crate::connection::connection_populate_endpoint_info`].
530///
531/// # Returns
532///
533/// Returns `true` when the condition checked by [`crate::connection::connection_populate_endpoint_info`] holds and `false` otherwise.
534///
535/// # Examples
536///
537/// ```rust,ignore
538/// let _result = pharos_runtime_core::connection::connection_populate_endpoint_info(todo!());
539/// ```
540///
541/// # Related
542///
543/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
544pub fn connection_populate_endpoint_info(connection: &mut NativeConnection) -> bool {
545    match connection.stream.as_ref() {
546        Some(NativeConnectionStream::Tcp(stream)) => {
547            connection.peer_info = stream.peer_addr().ok().map(|value| value.to_string());
548            connection.local_info = stream.local_addr().ok().map(|value| value.to_string());
549            true
550        }
551        #[cfg(unix)]
552        Some(NativeConnectionStream::Unix(_)) => true,
553        None => false,
554    }
555}
556
557/// Resets a connection to an empty metadata-only state.
558///
559/// # Parameters
560///
561/// - `connection`: Input consumed by [`crate::connection::connection_reset`].
562///
563/// # Returns
564///
565/// Returns after [`crate::connection::connection_reset`] applies its in-place effect.
566///
567/// # Examples
568///
569/// ```rust,ignore
570/// let _result = pharos_runtime_core::connection::connection_reset(todo!());
571/// ```
572///
573/// # Related
574///
575/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
576pub fn connection_reset(connection: &mut NativeConnection) {
577    connection.stream = None;
578    connection.fd = -1;
579    connection.write_fd = -1;
580    connection.peer_info = None;
581    connection.local_info = None;
582    connection.transport_type = NativeTransportType::Unknown;
583}
584
585/// Performs connection shutdown.
586///
587/// # Parameters
588///
589/// - `connection`: Input consumed by [`crate::connection::connection_shutdown`].
590///
591/// # Returns
592///
593/// Returns the computed value produced by [`crate::connection::connection_shutdown`].
594///
595/// # Examples
596///
597/// ```rust,ignore
598/// let _result = pharos_runtime_core::connection::connection_shutdown(todo!());
599/// ```
600///
601/// # Related
602///
603/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
604pub fn connection_shutdown(connection: &mut NativeConnection) -> i32 {
605    if connection.fd < 0 || !connection.close_fds {
606        return 0;
607    }
608    match connection.stream.as_mut() {
609        Some(NativeConnectionStream::Tcp(stream)) => {
610            stream.shutdown(Shutdown::Both).map(|_| 0).unwrap_or(-1)
611        }
612        #[cfg(unix)]
613        Some(NativeConnectionStream::Unix(stream)) => {
614            stream.shutdown(Shutdown::Both).map(|_| 0).unwrap_or(-1)
615        }
616        None => 0,
617    }
618}
619
620/// Performs connection peer info.
621///
622/// # Parameters
623///
624/// - `connection`: Input consumed by [`crate::connection::connection_peer_info`].
625///
626/// # Returns
627///
628/// Returns the computed value produced by [`crate::connection::connection_peer_info`].
629///
630/// # Examples
631///
632/// ```rust,ignore
633/// let _result = pharos_runtime_core::connection::connection_peer_info(todo!());
634/// ```
635///
636/// # Related
637///
638/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
639pub fn connection_peer_info(connection: &NativeConnection) -> &str {
640    connection.peer_info.as_deref().unwrap_or("unknown")
641}
642
643/// Performs connection local info.
644///
645/// # Parameters
646///
647/// - `connection`: Input consumed by [`crate::connection::connection_local_info`].
648///
649/// # Returns
650///
651/// Returns the computed value produced by [`crate::connection::connection_local_info`].
652///
653/// # Examples
654///
655/// ```rust,ignore
656/// let _result = pharos_runtime_core::connection::connection_local_info(todo!());
657/// ```
658///
659/// # Related
660///
661/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
662pub fn connection_local_info(connection: &NativeConnection) -> &str {
663    connection.local_info.as_deref().unwrap_or("unknown")
664}
665
666/// Performs connection transport type.
667///
668/// # Parameters
669///
670/// - `connection`: Input consumed by [`crate::connection::connection_transport_type`].
671///
672/// # Returns
673///
674/// Returns the computed value produced by [`crate::connection::connection_transport_type`].
675///
676/// # Examples
677///
678/// ```rust,ignore
679/// let _result = pharos_runtime_core::connection::connection_transport_type(todo!());
680/// ```
681///
682/// # Related
683///
684/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
685pub fn connection_transport_type(connection: &NativeConnection) -> NativeTransportType {
686    connection.transport_type
687}
688
689/// Performs connection transport type name.
690///
691/// # Parameters
692///
693/// - `connection`: Input consumed by [`crate::connection::connection_transport_type_name`].
694///
695/// # Returns
696///
697/// Returns the computed value produced by [`crate::connection::connection_transport_type_name`].
698///
699/// # Examples
700///
701/// ```rust,ignore
702/// let _result = pharos_runtime_core::connection::connection_transport_type_name(todo!());
703/// ```
704///
705/// # Related
706///
707/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
708pub fn connection_transport_type_name(connection: &NativeConnection) -> &'static str {
709    match connection_transport_type(connection) {
710        NativeTransportType::Tcp => "tcp",
711        NativeTransportType::Unix => "unix",
712        NativeTransportType::Unknown => "unknown",
713    }
714}
715
716/// Sends the complete buffer over the attached transport, retrying short writes.
717///
718/// # Parameters
719///
720/// - `connection`: Input consumed by [`crate::connection::connection_send`].
721/// - `buffer`: Input consumed by [`crate::connection::connection_send`].
722///
723/// # Returns
724///
725/// Returns the computed value produced by [`crate::connection::connection_send`].
726///
727/// # Examples
728///
729/// ```rust,ignore
730/// let _result = pharos_runtime_core::connection::connection_send(todo!(), &mut []);
731/// ```
732///
733/// # Related
734///
735/// - [`crate::connection`] for adjacent helpers that share the same runtime surface.
736pub fn connection_send(connection: &mut NativeConnection, buffer: &[u8]) -> i32 {
737    if buffer.is_empty() {
738        return 0;
739    }
740    let mut sent = 0usize;
741    while sent < buffer.len() {
742        let wrote = connection_write(connection, &buffer[sent..]);
743        if wrote <= 0 {
744            return -1;
745        }
746        sent = sent.saturating_add(wrote as usize);
747    }
748    sent as i32
749}