docs: enforce documentation on all public things
Signed-off-by: Charlotte Meyer <dev@buffet.sh>
This commit is contained in:
parent
009947fa29
commit
cafd3cafe1
10 changed files with 83 additions and 2 deletions
|
@ -1,4 +1,6 @@
|
|||
//! Contains the proc macro used to define builtins.
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use darling::FromMeta;
|
||||
use proc_macro::TokenStream;
|
||||
|
@ -16,6 +18,20 @@ struct AttrArgs {
|
|||
nofork: bool,
|
||||
}
|
||||
|
||||
/// Define a built in with the given description and name.
|
||||
///
|
||||
/// ```rust
|
||||
/// use oyster_builtin_proc::builtin;
|
||||
///
|
||||
/// #[builtin(
|
||||
/// name = "greet", // optionally override name
|
||||
/// description = "greets the user",
|
||||
/// nofork = true, // optionally don't fork, required for cd and similar
|
||||
/// )]
|
||||
/// fn hello(_shell: &mut Shell, _args: &[Cow<OsStr>]) {
|
||||
/// println!("Hello world!");
|
||||
/// }
|
||||
/// ```
|
||||
#[proc_macro_attribute]
|
||||
pub fn builtin(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let attrs = parse_macro_input!(attr as AttributeArgs);
|
||||
|
@ -49,7 +65,7 @@ pub fn builtin(attr: TokenStream, item: TokenStream) -> TokenStream {
|
|||
};
|
||||
|
||||
TokenStream::from(quote! {
|
||||
#[allow(non_upper_case_globals)]
|
||||
#[allow(non_upper_case_globals, missing_docs)]
|
||||
#vis static #ident: #builtin = {
|
||||
#fn_token #ident(#inputs) #block
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
//! Readline implementation used in oyster.
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::io::{self, Write};
|
||||
|
||||
/// Read a line from stdin and return it.
|
||||
pub fn readline(prompt: &str) -> Result<String, io::Error> {
|
||||
print!("{}", prompt);
|
||||
io::stdout().flush()?;
|
||||
|
|
|
@ -1,32 +1,46 @@
|
|||
//! Defines the abstract syntax tree of a valid program.
|
||||
use crate::{NodeKind, ParseError, ParseEvent, Parser};
|
||||
|
||||
/// Abtract, lossy representation of the syntax.
|
||||
/// Abtract, lossy representation of the syntax of an entire program.
|
||||
#[derive(Debug)]
|
||||
pub struct Code<'a>(pub Vec<Statement<'a>>);
|
||||
|
||||
/// A statement in a program.
|
||||
#[derive(Debug)]
|
||||
pub enum Statement<'a> {
|
||||
/// See [Pipeline].
|
||||
Pipeline(Pipeline<'a>),
|
||||
}
|
||||
|
||||
/// A pipeline consisting of multiple commands.
|
||||
#[derive(Debug)]
|
||||
pub struct Pipeline<'a>(pub Vec<Command<'a>>);
|
||||
|
||||
/// Redirects between commands in a [Pipeline].
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Redirect {
|
||||
/// No redirect.
|
||||
None,
|
||||
/// Stdout is getting redirected.
|
||||
Stdout,
|
||||
}
|
||||
|
||||
/// A command within a [Pipeline].
|
||||
#[derive(Debug)]
|
||||
pub struct Command<'a>(pub Vec<Word<'a>>, pub Redirect);
|
||||
|
||||
/// A word within a [Command].
|
||||
#[derive(Debug)]
|
||||
pub struct Word<'a>(pub Vec<WordPart<'a>>);
|
||||
|
||||
/// Part of a [Word].
|
||||
/// This can be anything from different parts of a quoted string, to escaped symbols, or even
|
||||
/// subcommands.
|
||||
#[derive(Debug)]
|
||||
pub enum WordPart<'a> {
|
||||
/// Plain text.
|
||||
Text(&'a str),
|
||||
/// A command substitution that needs to be run first.
|
||||
CommandSubstitution(Code<'a>),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,30 @@
|
|||
use crate::{NodeKind, ParseError, ParseEvent, Parser};
|
||||
|
||||
/// A concrete, loss-less representation of the parsed program.
|
||||
/// Only leafs contain actual code.
|
||||
#[derive(Debug)]
|
||||
pub enum ParseTree {
|
||||
/// A sub-tree in the program.
|
||||
/// These do not contain data.
|
||||
Tree {
|
||||
/// What kind of node are we dealing with.
|
||||
kind: NodeKind,
|
||||
/// The children of this tree.
|
||||
children: Vec<ParseTree>,
|
||||
},
|
||||
/// A leaf node.
|
||||
/// This contains all the code snippets.
|
||||
Leaf {
|
||||
/// What kind of node we are dealing with.
|
||||
kind: NodeKind,
|
||||
/// The length of the code referred to by this node.
|
||||
len: usize,
|
||||
},
|
||||
/// A parse error occured.
|
||||
Error {
|
||||
/// Which error occured.
|
||||
kind: ParseError,
|
||||
/// How much code to skip until recovery?
|
||||
len: usize,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -34,7 +34,10 @@ pub enum TokenKind {
|
|||
/// The parser is responsible for getting that information, if required.
|
||||
#[derive(Debug)]
|
||||
pub struct Token {
|
||||
/// The [TokenKind] of the token.
|
||||
pub kind: TokenKind,
|
||||
/// How long the token is.
|
||||
/// To actually get the code, you need to keep count yourself.
|
||||
pub len: usize,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! Parser for the oyster shell, the grammar is outlined below, `extras` are allowed everywhere,
|
||||
//! *except* inside `word`.
|
||||
|
|
|
@ -4,6 +4,7 @@ use crate::{lexer::Lexer, Token, TokenKind};
|
|||
|
||||
/// Errors that might occur during parsing.
|
||||
#[derive(Debug, Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum ParseError {
|
||||
#[error("unexpected pipe")]
|
||||
UnexpectedPipe,
|
||||
|
@ -16,8 +17,12 @@ pub enum ParseError {
|
|||
}
|
||||
|
||||
/// Type of the node.
|
||||
/// For specific information refer to [TokenKind].
|
||||
#[derive(Debug)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum NodeKind {
|
||||
// TokenKinds
|
||||
|
||||
Whitespace,
|
||||
Newlines,
|
||||
Semicolon,
|
||||
|
@ -29,6 +34,8 @@ pub enum NodeKind {
|
|||
EscapedChar,
|
||||
Comment,
|
||||
|
||||
// Nodes in the tree, that appear in the cst.
|
||||
|
||||
Program,
|
||||
CommandSubstitution,
|
||||
Pipeline,
|
||||
|
@ -36,6 +43,8 @@ pub enum NodeKind {
|
|||
Word,
|
||||
DQuotedString,
|
||||
|
||||
// Nodes in the tree, that don't appear in the cst.
|
||||
|
||||
/// Read a pipe but didn't start word yet.
|
||||
PipelineCont,
|
||||
}
|
||||
|
@ -43,9 +52,14 @@ pub enum NodeKind {
|
|||
/// Events required to build a syntax tree.
|
||||
#[derive(Debug)]
|
||||
pub enum ParseEvent {
|
||||
/// An error occured.
|
||||
Error(ParseError, usize),
|
||||
/// Start a new tree node.
|
||||
/// From now on, all nodes are child notes.
|
||||
StartNode(NodeKind),
|
||||
/// End the most recently started tree node.
|
||||
EndNode,
|
||||
/// A new leaf note.
|
||||
NewLeaf(NodeKind, usize),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! Standard math builtins.
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
ffi::OsStr,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
//! Definition of all the builtin builtins, and the general framework managing builtins.
|
||||
pub mod math;
|
||||
|
||||
use std::{borrow::Cow, collections::HashMap, ffi::OsStr};
|
||||
|
@ -6,11 +7,18 @@ use oyster_builtin_proc::builtin;
|
|||
|
||||
use crate::Shell;
|
||||
|
||||
/// Definition of a builtin.
|
||||
/// See [oyster_builtin_proc::builtin] for an easier way to generate them.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Builtin {
|
||||
/// Name of the builtin.
|
||||
pub name: &'static str,
|
||||
/// Description of the builtin, used in `help`.
|
||||
pub description: &'static str,
|
||||
/// Whether the builtin should fork when executed.
|
||||
/// Should be false for most builtins.
|
||||
pub nofork: bool,
|
||||
/// The actual function to call when the builtin runs.
|
||||
pub fun: fn(shell: &mut Shell, args: &[Cow<OsStr>]),
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
//! The runtime of the shell.
|
||||
//! This contains all the code related to actually running the program.
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! The runtime for executing oyster programs.
|
||||
//! Panics when an invalid ast gets passed.
|
||||
|
@ -33,14 +36,19 @@ use thiserror::Error;
|
|||
pub struct Status(pub i32);
|
||||
|
||||
impl Status {
|
||||
/// The command succeeded.
|
||||
pub const SUCCESS: Status = Status(0);
|
||||
/// The command failed to execute (most likely permissions).
|
||||
pub const COULD_NOT_EXEC: Status = Status(126);
|
||||
/// The command could not be found.
|
||||
pub const COMMAND_NOT_FOUND: Status = Status(127);
|
||||
/// The base whch signals get added onto, i.e. SIGINT (2) results in 130.
|
||||
pub const SIG_BASE: Status = Status(128);
|
||||
}
|
||||
|
||||
/// Errors that occur during runtime.
|
||||
#[derive(Debug, Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum RuntimeError {
|
||||
#[error("failed to create pipe: {0}")]
|
||||
PipeCreationFailed(#[source] nix::Error),
|
||||
|
@ -67,6 +75,7 @@ pub enum RuntimeError {
|
|||
IOError(#[source] io::Error),
|
||||
}
|
||||
|
||||
/// The main "app struct", containing all the data related to the current shell instance.
|
||||
pub struct Shell {
|
||||
is_running: bool,
|
||||
builtins: BuiltinMap,
|
||||
|
|
Loading…
Reference in a new issue