Documentation
/*
==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--==--

Namaste

Copyright (C) 2019, 2021-2023  Anonymous

There are several releases over multiple years,
they are listed as ranges, such as: "2021-2023".

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--::--
*/

use {
    std::os::{
        fd::FromRawFd,
        linux::net::SocketAddrExt,
        unix::net::{SocketAddr, UnixListener, UnixStream},
    },
    crate::{Result, UdsxUnixStream},
    super::{Namaste, RwNamaste},
};

impl<R, W> RwNamaste<R, W> where R: AsRef<[u8]>, W: AsRef<[u8]> {

    /// # Takes a read
    pub fn read(&mut self) -> Result<()> {
        loop {
            match &self.read {
                None => {
                    let read = match Namaste::make(&self.read_id) {
                        Ok(namaste) => namaste,
                        Err(_) => match self.connect_to(&self.read_id) {
                            Ok(stream) => Namaste::make_from_unix_listener(unsafe {
                                UnixListener::from_raw_fd(stream.recv_streams::<_, _, 1>(crate::linux::STREAM_ID)?[usize::MIN])
                            })?,
                            Err(_) => continue,
                        },
                    };
                    return match self.connect_to(&self.write_id) {
                        Ok(_) => Err(err!("Another write is working")),
                        Err(_) => Ok(self.read = Some(read)),
                    };
                },
                Some(_) => return Ok(()),
            };
        }
    }

    /// # Connects to a server
    fn connect_to<B>(&self, address: B) -> Result<UnixStream> where B: AsRef<[u8]> {
        UnixStream::connect_addr(&SocketAddr::from_abstract_name(address)?)
    }

    /// # Takes a write
    pub fn write(&mut self) -> Result<()> {
        match &self.write {
            None => {
                let write = Namaste::make(&self.write_id)?;
                match self.connect_to(&self.read_id) {
                    Ok(_) => Err(err!("Another read is working")),
                    Err(_) => Ok(self.write = Some(write)),
                }
            },
            Some(_) => Ok(()),
        }
    }

}