#![stable(feature = "os_fd", since = "1.66.0")]

use crate::sys_common::{AsInner, FromInner};

#[stable(feature = "rust1", since = "1.0.0")]
pub type RawFd = yggdrasil_rt::io::RawFd;

macro_rules! stdio_impl_as_raw_fd {
    ($($ty:ty => $n:expr),*) => {$(
        #[stable(feature = "asraw_stdio", since = "1.21.0")]
        impl AsRawFd for $ty {
            #[inline]
            fn as_raw_fd(&self) -> RawFd {
                $n
            }
        }

        #[stable(feature = "asraw_stdio", since = "1.21.0")]
        impl AsRawFd for &$ty {
            #[inline]
            fn as_raw_fd(&self) -> RawFd {
                $n
            }
        }
    )*};
}

#[stable(feature = "rust1", since = "1.0.0")]
pub trait AsRawFd {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn as_raw_fd(&self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
pub trait FromRawFd {
    #[stable(feature = "rust1", since = "1.0.0")]
    unsafe fn from_raw_fd(fd: RawFd) -> Self;
}

#[stable(feature = "rust1", since = "1.0.0")]
pub trait IntoRawFd {
    #[stable(feature = "rust1", since = "1.0.0")]
    fn into_raw_fd(self) -> RawFd;
}

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for RawFd {
    fn as_raw_fd(&self) -> RawFd {
        *self
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromRawFd for RawFd {
    unsafe fn from_raw_fd(fd: RawFd) -> Self {
        fd
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl IntoRawFd for RawFd {
    fn into_raw_fd(self) -> RawFd {
        self
    }
}

stdio_impl_as_raw_fd!(
    crate::io::Stdin => RawFd::STDIN,
    crate::io::Stdout => RawFd::STDOUT,
    crate::io::Stderr => RawFd::STDERR
);

#[stable(feature = "rust1", since = "1.0.0")]
impl AsRawFd for crate::fs::File {
    fn as_raw_fd(&self) -> RawFd {
        self.as_inner().as_raw_fd()
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl FromRawFd for crate::fs::File {
    unsafe fn from_raw_fd(fd: RawFd) -> Self {
        let inner = crate::sys::fs::File::from_raw_fd(fd);
        crate::fs::File::from_inner(inner)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> AsRawFd for crate::io::StdinLock<'a> {
    fn as_raw_fd(&self) -> RawFd {
        todo!()
    }
}
