mirror of
https://github.com/nushell/nushell.git
synced 2025-06-30 22:50:14 +02:00
Add some comments (#1225)
This commit is contained in:
@ -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<String>,
|
||||
actual: Spanned<impl Into<String>>,
|
||||
|
@ -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<Span>) -> 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<Item = &PathMember> {
|
||||
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<DebugDocBuilder> =
|
||||
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<Span> {
|
||||
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<String>, span: impl Into<Span>) -> PathMember {
|
||||
UnspannedPathMember::String(string.into()).into_path_member(span)
|
||||
}
|
||||
|
||||
/// Create a numeric path member
|
||||
pub fn int(int: impl Into<BigInt>, span: impl Into<Span>) -> 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<Vec<(usize, String)>> {
|
||||
let field_tried = match &field_tried.unspanned {
|
||||
UnspannedPathMember::String(string) => string.clone(),
|
||||
|
@ -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<i64, ShellError> {
|
||||
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<String, ShellError> {
|
||||
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<u8> {
|
||||
type Error = ShellError;
|
||||
|
||||
/// Convert to a u8 vec, if possible
|
||||
fn try_from(value: &Value) -> Result<Vec<u8>, ShellError> {
|
||||
match &value.value {
|
||||
UntaggedValue::Primitive(Primitive::Binary(b)) => Ok(b.clone()),
|
||||
@ -43,6 +46,7 @@ impl std::convert::TryFrom<&Value> for Vec<u8> {
|
||||
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),
|
||||
|
@ -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"),
|
||||
|
@ -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<H: Hasher>(&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<Ordering> {
|
||||
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<Value> 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<Value> 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<IndexMap<String, Value>> for Dictionary {
|
||||
/// Create a dictionary from a map of strings to Values
|
||||
fn from(input: IndexMap<String, Value>) -> Dictionary {
|
||||
let mut out = IndexMap::default();
|
||||
|
||||
@ -106,6 +115,7 @@ impl From<IndexMap<String, Value>> 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<Item = &String> {
|
||||
self.entries.keys()
|
||||
}
|
||||
|
||||
/// Find the matching Value for a key, if possible
|
||||
pub fn get_data_by_key(&self, name: Spanned<&str>) -> Option<Value> {
|
||||
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<Tag>) -> 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<Tag>, block: impl FnOnce(&mut TaggedDictBuilder)) -> Value {
|
||||
let mut builder = TaggedDictBuilder::new(tag);
|
||||
block(&mut builder);
|
||||
|
Reference in New Issue
Block a user