dope 0.8.0

The manifold runtime
Documentation
use std::io;
use std::marker::PhantomData;
use std::os::fd::{BorrowedFd, OwnedFd};
use std::rc::Rc;

use dope_core::io::fd::Fd;

#[derive(Debug)]
enum Kind<'d> {
    Direct(Rc<OwnedFd>),
    Fixed(Rc<Fd<'d>>),
}

#[derive(Debug)]
pub struct Source<'d, K = Direct> {
    kind: Kind<'d>,
    marker: PhantomData<K>,
}

#[derive(Debug)]
pub enum Direct {}

#[derive(Debug)]
pub enum Fixed {}

#[doc(hidden)]
pub enum SourceRef<'d> {
    Direct(Rc<OwnedFd>),
    Fixed(Rc<Fd<'d>>),
}

impl<'d> Source<'d, Direct> {
    pub fn from_owned_fd(fd: OwnedFd) -> Self {
        Self::owned(fd)
    }

    pub fn try_from_fd(fd: BorrowedFd<'_>) -> io::Result<Self> {
        fd.try_clone_to_owned().map(Self::from_owned_fd)
    }

    #[doc(hidden)]
    pub fn direct(&self) -> Rc<OwnedFd> {
        match &self.kind {
            Kind::Direct(fd) => Rc::clone(fd),
            Kind::Fixed(_) => unreachable!(),
        }
    }

    #[doc(hidden)]
    pub fn owned(fd: OwnedFd) -> Self {
        Self {
            kind: Kind::Direct(Rc::new(fd)),
            marker: PhantomData,
        }
    }
}

impl<'d> Source<'d, Fixed> {
    #[doc(hidden)]
    pub fn fixed(fd: Fd<'d>) -> Self {
        Self {
            kind: Kind::Fixed(Rc::new(fd)),
            marker: PhantomData,
        }
    }
}

impl<'d, K> Source<'d, K> {
    pub fn is_fixed(&self) -> bool {
        matches!(self.kind, Kind::Fixed(_))
    }

    #[doc(hidden)]
    pub fn lease(&self) -> SourceRef<'d> {
        match &self.kind {
            Kind::Direct(fd) => SourceRef::Direct(Rc::clone(fd)),
            Kind::Fixed(fd) => SourceRef::Fixed(Rc::clone(fd)),
        }
    }
}