Enforce documentation for ABI crate

This commit is contained in:
Mark Poliakov 2023-07-20 12:38:38 +03:00
parent 5541cc3214
commit 21c610c1a0
6 changed files with 102 additions and 39 deletions

View File

@ -1,28 +1,47 @@
//! Error definitions and conversion functions
use crate::{io::RawFd, primitive_enum};
primitive_enum!(pub enum Error: u32 {
OutOfMemory = 1,
InvalidMemoryOperation = 2,
AlreadyExists = 3,
TimedOut = 4,
InvalidArgument = 5,
DoesNotExist = 6,
IsADirectory = 7,
InvalidFile = 8,
NotImplemented = 9,
NotADirectory = 10,
});
primitive_enum!(
#[doc = "Describes an error reported by the kernel"]
pub enum Error: u32 {
#[doc = "Kernel ran out of virtual address space or physical memory"]
OutOfMemory = 1,
#[doc = "Attempted to perform an illegal memory operation"]
InvalidMemoryOperation = 2,
#[doc = "Entry/file already exists"]
AlreadyExists = 3,
#[doc = "Operation timed out"]
TimedOut = 4,
#[doc = "Invalid argument supplied to a kernel function"]
InvalidArgument = 5,
#[doc = "Entry/file does not exist"]
DoesNotExist = 6,
#[doc = "A directory found where something else was expected"]
IsADirectory = 7,
#[doc = "Invalid file descriptor supplied to a kernel function"]
InvalidFile = 8,
#[doc = "Kernel/driver function is not implemented"]
NotImplemented = 9,
#[doc = "Entry is not a directory"]
NotADirectory = 10,
}
);
pub trait FromSyscallResult: Sized {
/// Interface for converting between system call result representations
pub trait SyscallResult: Sized {
/// Converts raw value into a system call result
fn from_syscall_result(value: usize) -> Result<Self, Error>;
}
pub trait IntoSyscallResult {
/// Converts system call result into a raw value
fn into_syscall_result(self) -> usize;
}
/// Interface for converting between system call error representations
pub trait SyscallError {
/// Converts raw value into a system call error
fn from_syscall_error(value: usize) -> Self;
/// Converts system call error into a raw value
fn into_syscall_error(self) -> usize;
}
@ -36,16 +55,20 @@ impl SyscallError for Error {
}
}
impl<T: IntoSyscallResult> IntoSyscallResult for Result<T, Error> {
impl<T: SyscallResult> SyscallResult for Result<T, Error> {
fn into_syscall_result(self) -> usize {
match self {
Ok(t) => t.into_syscall_result(),
Err(e) => e.into_syscall_error(),
}
}
fn from_syscall_result(_value: usize) -> Result<Self, Error> {
todo!()
}
}
impl FromSyscallResult for () {
impl SyscallResult for () {
fn from_syscall_result(value: usize) -> Result<Self, Error> {
if (value as isize) < 0 {
Err(Error::from_syscall_error(value))
@ -54,15 +77,13 @@ impl FromSyscallResult for () {
Ok(())
}
}
}
impl IntoSyscallResult for () {
fn into_syscall_result(self) -> usize {
0
}
}
impl FromSyscallResult for usize {
impl SyscallResult for usize {
fn from_syscall_result(value: usize) -> Result<Self, Error> {
if (value as isize) < 0 {
Err(Error::from_syscall_error(value))
@ -70,16 +91,14 @@ impl FromSyscallResult for usize {
Ok(value)
}
}
}
impl IntoSyscallResult for usize {
fn into_syscall_result(self) -> usize {
assert!((self as isize) >= 0);
self
}
}
impl FromSyscallResult for RawFd {
impl SyscallResult for RawFd {
fn from_syscall_result(value: usize) -> Result<Self, Error> {
if (value as isize) < 0 {
Err(Error::from_syscall_error(value))
@ -88,9 +107,7 @@ impl FromSyscallResult for RawFd {
Ok(RawFd(value as u32))
}
}
}
impl IntoSyscallResult for RawFd {
fn into_syscall_result(self) -> usize {
self.0 as usize
}

View File

@ -1,24 +1,33 @@
//! I/O control data structures
use core::fmt;
/// Raw file descriptor representation
#[derive(Clone, Copy, PartialEq, Debug, PartialOrd, Ord, Eq)]
#[repr(transparent)]
pub struct RawFd(pub u32);
/// Describes how a file should be opened
#[derive(Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub struct OpenFlags(pub u32);
/// Describes how a mount operation should be performed
#[derive(Clone, Debug)]
#[repr(C)]
pub struct MountOptions {
/// Block device to use as a mount source. May be empty when mounting virtual filesystems.
pub source: Option<&'static str>,
/// Filesystem to use when mounting. Empty means "deduce automatically" and source must be set.
pub filesystem: Option<&'static str>,
/// Path to a directory to mount the filesystem to
pub target: &'static str,
}
/// Describes how an unmount operation should be performed
#[derive(Clone, Debug)]
#[repr(C)]
pub struct UnmountOptions {
/// Path to the mountpoint to unmount
pub mountpoint: &'static str,
}
@ -26,29 +35,36 @@ const O_READ: u32 = 1 << 0;
const O_WRITE: u32 = 1 << 1;
impl RawFd {
/// Default output descriptor of a process
pub const STDOUT: Self = Self(1);
/// Error output descriptor of a process
pub const STDERR: Self = Self(2);
}
impl OpenFlags {
/// Constructs an empty open option set
pub fn new() -> Self {
Self(0)
}
/// Enables read operation
pub const fn read(mut self) -> Self {
self.0 |= O_READ;
self
}
/// Enables write operation
pub const fn write(mut self) -> Self {
self.0 |= O_WRITE;
self
}
/// Returns `true` if [OpenFlags] includes read capability
pub const fn is_read(self) -> bool {
self.0 & O_READ != 0
}
/// Returns `true` if [OpenFlags] includes write capability
pub const fn is_write(self) -> bool {
self.0 & O_WRITE != 0
}

View File

@ -1,5 +1,7 @@
//! Yggdrasil OS user-kernel communication ABI
#![no_std]
#![feature(trace_macros)]
#![deny(missing_docs)]
pub(crate) mod macros;

View File

@ -1,10 +1,15 @@
/// Helper macro to define primitive enums with integer reprs, as well as their conversion methods
#[macro_export]
macro_rules! primitive_enum {
($vis:vis enum $name:ident: $repr:ty { $( $variant:ident = $discriminant:literal, )+ }) => {
($(#[doc = $enum_doc:expr])? $vis:vis enum $name:ident: $repr:ty {
$( $(#[doc = $doc:expr])? $variant:ident = $discriminant:literal, )+
}) => {
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr($repr)]
$(#[doc = $enum_doc])?
$vis enum $name {
$(
$(#[doc = $doc])?
$variant = $discriminant
),+
}

View File

@ -1,9 +1,16 @@
//! Filesystem path definitions and manipulation functions
/// Parent directory path element
pub const PARENT_NAME: &'static str = "..";
/// Path element that refers to itself
pub const SELF_NAME: &'static str = ".";
/// String representation of a path separator
pub const SEPARATOR_STR: &'static str = "/";
/// Character that separates the path elements
pub const SEPARATOR: char = '/';
/// Splits a path, returning the first element and the rest
pub fn split_left(path: &str) -> (&str, &str) {
if let Some((left, right)) = path.split_once(SEPARATOR) {
(left, right.trim_start_matches(SEPARATOR))
@ -12,6 +19,7 @@ pub fn split_left(path: &str) -> (&str, &str) {
}
}
/// Splits a path, returning the last element and the path preceding it
pub fn split_right(path: &str) -> (&str, &str) {
if let Some((left, right)) = path.trim_end_matches(SEPARATOR).rsplit_once(SEPARATOR) {
(left.trim_end_matches(SEPARATOR), right)

View File

@ -1,17 +1,32 @@
//! System call function definitions
use crate::primitive_enum;
primitive_enum!(pub enum SyscallFunction: usize {
Exit = 1,
Nanosleep = 2,
MapMemory = 3,
UnmapMemory = 4,
Write = 5,
Read = 6,
Open = 7,
Close = 8,
primitive_enum!(
#[doc = "Describes a system call issued to the kernel"]
pub enum SyscallFunction: usize {
#[doc = "Terminate the caller task"]
Exit = 1,
#[doc = "Suspend the caller task for some time"]
Nanosleep = 2,
#[doc = "Map a virtual memory region"]
MapMemory = 3,
#[doc = "Release a virtual memory region"]
UnmapMemory = 4,
#[doc = "Write data to a file descriptor"]
Write = 5,
#[doc = "Read data from a file descriptor"]
Read = 6,
#[doc = "Open a file"]
Open = 7,
#[doc = "Close a file descriptor"]
Close = 8,
Mount = 101,
Unmount = 102,
#[doc = "Mount a filesystem"]
Mount = 101,
#[doc = "Unmount a filesystem"]
Unmount = 102,
DebugTrace = 128,
});
#[doc = "Print a message to the kernel's debug trace output"]
DebugTrace = 128,
}
);