socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation
/*-
 * socket9 - A RAW networking sockets manipulation and configration basing on 
 * strong types.
 * 
 * Copyright (C) 2021 Aleksandr Morozov, Lucia Hoffmann
 * Copyright (C) 2025 Aleksandr Morozov
 * 
 * The syslog-rs crate can be redistributed and/or modified
 * under the terms of either of the following licenses:
 *
 *   1. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016 OR
 *
 *   2. the Mozilla Public License Version 2.0 (the “MPL”) OR
 *                     
 *   3. The MIT License (MIT)
 */

use std::cmp::min;
use std::ffi::c_int;

use std::fmt;
use std::time::Duration;

use crate::{OptRMarker, OptWMarker, SockOptMarker};

use crate::
{
    SO_RCVTIMEO, SOL_SOCKET, timeval, time_t, suseconds_t
};

/// > set timeout value for input
#[repr(transparent)]
#[derive(Clone, Copy)]
pub struct SoRcvTimeout(timeval);

#[cfg(unix)]
impl fmt::Debug for SoRcvTimeout
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
    {
        f.debug_tuple("SoRcvTimeout").field(&self.0).finish()
    }
}

#[cfg(windows)]
impl fmt::Debug for SoRcvTimeout
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
    {
        f.debug_tuple("SoRcvTimeout").finish()
    }
}

impl SockOptMarker for SoRcvTimeout 
{
    const SO_LEVEL: c_int = SOL_SOCKET;   
    const SO_OPTNAME: c_int = SO_RCVTIMEO;

    type DataType = Option<Duration>;
    type InputType = timeval;

    #[inline]
    fn from(value: Self::InputType) -> Self 
    {
        return Self(value);
    }

    #[inline]
    fn get(self) -> Self::DataType
    {
        if self.0.tv_sec == 0 && self.0.tv_usec == 0 
        {
            return None;
        } 
        else 
        {
            let sec = self.0.tv_sec as u64;
            let nsec = (self.0.tv_usec as u32) * 1000;

            return Some(Duration::new(sec, nsec));
        }
    }

    fn from_user(sz: Self::DataType) -> Self where Self: Sized
    {
        return Self(
            sz
                .map_or(
                    timeval{ tv_sec: 0, tv_usec: 0 },
                    |v| 
                    timeval
                    { 
                        tv_sec: min(v.as_secs(), time_t::MAX as u64) as time_t,
                        tv_usec: v.subsec_micros() as suseconds_t,
                    }
                )
        );
    }
}


impl OptRMarker for SoRcvTimeout {}
impl OptWMarker for SoRcvTimeout {}