diff --git a/crates/nu-errors/src/lib.rs b/crates/nu-errors/src/lib.rs index bf5f92293c..8b16d2c281 100644 --- a/crates/nu-errors/src/lib.rs +++ b/crates/nu-errors/src/lib.rs @@ -304,6 +304,7 @@ impl serde::de::Error for ShellError { } impl ShellError { + /// An error that describes a mismatch between the given type and the expected type pub fn type_error( expected: impl Into, actual: Spanned>, diff --git a/crates/nu-protocol/src/value/column_path.rs b/crates/nu-protocol/src/value/column_path.rs index 990327218e..9ee048751a 100644 --- a/crates/nu-protocol/src/value/column_path.rs +++ b/crates/nu-protocol/src/value/column_path.rs @@ -5,6 +5,7 @@ use nu_source::{b, span_for_spanned_list, DebugDocBuilder, HasFallibleSpan, Pret use num_bigint::BigInt; use serde::{Deserialize, Serialize}; +/// A PathMember that has yet to be spanned so that it can be used in later processing #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub enum UnspannedPathMember { String(String), @@ -12,6 +13,7 @@ pub enum UnspannedPathMember { } impl UnspannedPathMember { + /// Add the span information and get a full PathMember pub fn into_path_member(self, span: impl Into) -> PathMember { PathMember { unspanned: self, @@ -20,6 +22,7 @@ impl UnspannedPathMember { } } +/// A basic piece of a ColumnPath, which describes the steps to take through a table to arrive a cell, row, or inner table #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] pub struct PathMember { pub unspanned: UnspannedPathMember, @@ -27,6 +30,7 @@ pub struct PathMember { } impl PrettyDebug for &PathMember { + /// Gets the PathMember ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { match &self.unspanned { UnspannedPathMember::String(string) => b::primitive(format!("{:?}", string)), @@ -35,6 +39,10 @@ impl PrettyDebug for &PathMember { } } +/// The fundamental path primitive to descrive how to navigate through a table to get to a sub-item. A path member can be either a word or a number. Words/strings are taken to mean +/// a column name, and numbers are the row number. Taken together they describe which column or row to narrow to in order to get data. +/// +/// Rows must follow column names, they can't come first. eg) `foo.1` is valid where `1.foo` is not. #[derive( Debug, Hash, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq, Getters, Clone, new, )] @@ -44,16 +52,19 @@ pub struct ColumnPath { } impl ColumnPath { + /// Iterate over the members of the column path pub fn iter(&self) -> impl Iterator { self.members.iter() } + /// Returns the last member and a slice of the remaining members pub fn split_last(&self) -> Option<(&PathMember, &[PathMember])> { self.members.split_last() } } impl PrettyDebug for ColumnPath { + /// Gets the ColumnPath ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { let members: Vec = self.members.iter().map(|member| member.pretty()).collect(); @@ -68,6 +79,7 @@ impl PrettyDebug for ColumnPath { } impl HasFallibleSpan for ColumnPath { + /// Creates a span that will cover the column path, if possible fn maybe_span(&self) -> Option { if self.members.is_empty() { None @@ -78,15 +90,18 @@ impl HasFallibleSpan for ColumnPath { } impl PathMember { + /// Create a string path member pub fn string(string: impl Into, span: impl Into) -> PathMember { UnspannedPathMember::String(string.into()).into_path_member(span) } + /// Create a numeric path member pub fn int(int: impl Into, span: impl Into) -> PathMember { UnspannedPathMember::Int(int.into()).into_path_member(span) } } +/// Prepares a list of "sounds like" matches for the string you're trying to find pub fn did_you_mean(obj_source: &Value, field_tried: &PathMember) -> Option> { let field_tried = match &field_tried.unspanned { UnspannedPathMember::String(string) => string.clone(), diff --git a/crates/nu-protocol/src/value/convert.rs b/crates/nu-protocol/src/value/convert.rs index 739d87b6e1..bdff4fe307 100644 --- a/crates/nu-protocol/src/value/convert.rs +++ b/crates/nu-protocol/src/value/convert.rs @@ -8,6 +8,7 @@ use nu_source::TaggedItem; impl std::convert::TryFrom<&Value> for i64 { type Error = ShellError; + /// Convert to an i64 integer, if possible fn try_from(value: &Value) -> Result { match &value.value { UntaggedValue::Primitive(Primitive::Int(int)) => { @@ -21,6 +22,7 @@ impl std::convert::TryFrom<&Value> for i64 { impl std::convert::TryFrom<&Value> for String { type Error = ShellError; + /// Convert to a string, if possible fn try_from(value: &Value) -> Result { match &value.value { UntaggedValue::Primitive(Primitive::String(s)) => Ok(s.clone()), @@ -32,6 +34,7 @@ impl std::convert::TryFrom<&Value> for String { impl std::convert::TryFrom<&Value> for Vec { type Error = ShellError; + /// Convert to a u8 vec, if possible fn try_from(value: &Value) -> Result, ShellError> { match &value.value { UntaggedValue::Primitive(Primitive::Binary(b)) => Ok(b.clone()), @@ -43,6 +46,7 @@ impl std::convert::TryFrom<&Value> for Vec { impl<'a> std::convert::TryFrom<&'a Value> for &'a Dictionary { type Error = ShellError; + /// Convert to a dictionary, if possible fn try_from(value: &'a Value) -> Result<&'a Dictionary, ShellError> { match &value.value { UntaggedValue::Row(d) => Ok(d), diff --git a/crates/nu-protocol/src/value/debug.rs b/crates/nu-protocol/src/value/debug.rs index f089b82b2c..87c3410ce5 100644 --- a/crates/nu-protocol/src/value/debug.rs +++ b/crates/nu-protocol/src/value/debug.rs @@ -4,12 +4,14 @@ use crate::value::{UntaggedValue, Value}; use nu_source::{b, DebugDocBuilder, PrettyDebug}; impl PrettyDebug for &Value { + /// Get a borrowed Value ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { PrettyDebug::pretty(*self) } } impl PrettyDebug for Value { + /// Get a Value ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { match &self.value { UntaggedValue::Primitive(p) => p.pretty(), @@ -24,6 +26,7 @@ impl PrettyDebug for Value { } impl PrettyType for Primitive { + /// Find the type of the Value and prepare it for pretty-printing fn pretty_type(&self) -> DebugDocBuilder { match self { Primitive::Nothing => ty("nothing"), @@ -47,6 +50,7 @@ impl PrettyType for Primitive { } impl PrettyDebug for Primitive { + /// Get a Primitive value ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { match self { Primitive::Nothing => b::primitive("nothing"), diff --git a/crates/nu-protocol/src/value/dict.rs b/crates/nu-protocol/src/value/dict.rs index cbef720445..03217fca51 100644 --- a/crates/nu-protocol/src/value/dict.rs +++ b/crates/nu-protocol/src/value/dict.rs @@ -9,6 +9,7 @@ use serde::{Deserialize, Serialize}; use std::cmp::{Ord, Ordering, PartialOrd}; use std::hash::{Hash, Hasher}; +/// A dictionary that can hold a mapping from names to Values #[derive(Debug, Default, Serialize, Deserialize, PartialEq, Eq, Clone, Getters, new)] pub struct Dictionary { #[get = "pub"] @@ -17,6 +18,7 @@ pub struct Dictionary { #[allow(clippy::derive_hash_xor_eq)] impl Hash for Dictionary { + /// Create the hash function to allow the Hash trait for dictionaries fn hash(&self, state: &mut H) { let mut entries = self.entries.clone(); entries.sort_keys(); @@ -26,6 +28,7 @@ impl Hash for Dictionary { } impl PartialOrd for Dictionary { + /// Compare two dictionaries for sort ordering fn partial_cmp(&self, other: &Dictionary) -> Option { let this: Vec<&String> = self.entries.keys().collect(); let that: Vec<&String> = other.entries.keys().collect(); @@ -42,6 +45,7 @@ impl PartialOrd for Dictionary { } impl Ord for Dictionary { + /// Compare two dictionaries for ordering fn cmp(&self, other: &Dictionary) -> Ordering { let this: Vec<&String> = self.entries.keys().collect(); let that: Vec<&String> = other.entries.keys().collect(); @@ -58,6 +62,7 @@ impl Ord for Dictionary { } impl PartialEq for Dictionary { + /// Test a dictionary against a Value for equality fn eq(&self, other: &Value) -> bool { match &other.value { UntaggedValue::Row(d) => self == d, @@ -66,6 +71,7 @@ impl PartialEq for Dictionary { } } +/// A key-value pair specifically meant to be used in debug and pretty-printing #[derive(Debug, new)] struct DebugEntry<'a> { key: &'a str, @@ -73,12 +79,14 @@ struct DebugEntry<'a> { } impl<'a> PrettyDebug for DebugEntry<'a> { + /// Build the the information to pretty-print the DebugEntry fn pretty(&self) -> DebugDocBuilder { (b::key(self.key.to_string()) + b::equals() + self.value.pretty().into_value()).group() } } impl PrettyDebug for Dictionary { + /// Get a Dictionary ready to be pretty-printed fn pretty(&self) -> DebugDocBuilder { b::delimit( "(", @@ -94,6 +102,7 @@ impl PrettyDebug for Dictionary { } impl From> for Dictionary { + /// Create a dictionary from a map of strings to Values fn from(input: IndexMap) -> Dictionary { let mut out = IndexMap::default(); @@ -106,6 +115,7 @@ impl From> for Dictionary { } impl Dictionary { + /// Find the matching Value for a given key, if possible. If not, return a Primitive::Nothing pub fn get_data(&self, desc: &str) -> MaybeOwned<'_, Value> { match self.entries.get(desc) { Some(v) => MaybeOwned::Borrowed(v), @@ -115,10 +125,12 @@ impl Dictionary { } } + /// Iterate the keys in the Dictionary pub fn keys(&self) -> impl Iterator { self.entries.keys() } + /// Find the matching Value for a key, if possible pub fn get_data_by_key(&self, name: Spanned<&str>) -> Option { let result = self .entries @@ -134,6 +146,7 @@ impl Dictionary { ) } + /// Get a mutable entry that matches a key, if possible pub fn get_mut_data_by_key(&mut self, name: &str) -> Option<&mut Value> { match self .entries @@ -145,11 +158,13 @@ impl Dictionary { } } + /// Insert a new key/value pair into the dictionary pub fn insert_data_at_key(&mut self, name: &str, value: Value) { self.entries.insert(name.to_string(), value); } } +/// A helper to help create dictionaries for you. It has the ability to insert values into the dictionary while maintaining the tags that need to be applied to the individual members #[derive(Debug)] pub struct TaggedDictBuilder { tag: Tag, @@ -157,6 +172,7 @@ pub struct TaggedDictBuilder { } impl TaggedDictBuilder { + /// Create a new builder pub fn new(tag: impl Into) -> TaggedDictBuilder { TaggedDictBuilder { tag: tag.into(), @@ -164,6 +180,7 @@ impl TaggedDictBuilder { } } + /// Build the contents of the builder into a Value pub fn build(tag: impl Into, block: impl FnOnce(&mut TaggedDictBuilder)) -> Value { let mut builder = TaggedDictBuilder::new(tag); block(&mut builder); diff --git a/src/cli.rs b/src/cli.rs index db275ff30e..3191c7055c 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -226,6 +226,7 @@ impl History { } } +/// The entry point for the CLI. Will register all known internal commands, load experimental commands, load plugins, then prepare the prompt and line reader for input. pub async fn cli() -> Result<(), Box> { let mut context = Context::basic()?; @@ -560,6 +561,7 @@ enum LineResult { Break, } +/// Process the line by parsing the text to turn it into commands, classify those commands so that we understand what is being called in the pipeline, and then run this pipeline async fn process_line(readline: Result, ctx: &mut Context) -> LineResult { match &readline { Ok(line) if line.trim() == "" => LineResult::Success(line.clone()),