forked from extern/nushell
parent
37f10cf273
commit
26e77a4b05
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2584,6 +2584,7 @@ dependencies = [
|
||||
"typetag",
|
||||
"umask",
|
||||
"unicode-xid",
|
||||
"url",
|
||||
"users",
|
||||
"uuid",
|
||||
"which",
|
||||
|
@ -34,7 +34,7 @@ codespan-reporting = "0.9.5"
|
||||
csv = "1.1"
|
||||
ctrlc = {version = "3.1.4", optional = true}
|
||||
derive-new = "0.5.8"
|
||||
directories = {version = "2.0.2", optional = true}
|
||||
directories = {version = "2.0.2", optional = true}
|
||||
dirs = {version = "2.0.2", optional = true}
|
||||
dunce = "1.0.1"
|
||||
eml-parser = "0.1.0"
|
||||
@ -94,6 +94,7 @@ rayon = "1.3.1"
|
||||
starship = {version = "0.43.0", optional = true}
|
||||
trash = {version = "1.0.1", optional = true}
|
||||
quick-xml = "0.18.1"
|
||||
url = {version = "2.1.1"}
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
users = "0.10.0"
|
||||
|
@ -420,6 +420,12 @@ pub fn create_default_context(
|
||||
whole_stream_command(PathExpand),
|
||||
whole_stream_command(PathExists),
|
||||
whole_stream_command(PathType),
|
||||
// Url
|
||||
whole_stream_command(UrlCommand),
|
||||
whole_stream_command(UrlScheme),
|
||||
whole_stream_command(UrlPath),
|
||||
whole_stream_command(UrlHost),
|
||||
whole_stream_command(UrlQuery),
|
||||
]);
|
||||
|
||||
#[cfg(feature = "clipboard")]
|
||||
|
@ -115,6 +115,7 @@ pub(crate) mod to_yaml;
|
||||
pub(crate) mod trim;
|
||||
pub(crate) mod uniq;
|
||||
pub(crate) mod update;
|
||||
pub(crate) mod url_;
|
||||
pub(crate) mod version;
|
||||
pub(crate) mod what;
|
||||
pub(crate) mod where_;
|
||||
@ -247,6 +248,7 @@ pub(crate) use to_yaml::ToYAML;
|
||||
pub(crate) use touch::Touch;
|
||||
pub(crate) use trim::Trim;
|
||||
pub(crate) use uniq::Uniq;
|
||||
pub(crate) use url_::{UrlCommand, UrlHost, UrlPath, UrlQuery, UrlScheme};
|
||||
pub(crate) use version::Version;
|
||||
pub(crate) use what::What;
|
||||
pub(crate) use where_::Where;
|
||||
|
46
crates/nu-cli/src/commands/url_/command.rs
Normal file
46
crates/nu-cli/src/commands/url_/command.rs
Normal file
@ -0,0 +1,46 @@
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||
|
||||
pub struct Url;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for Url {
|
||||
fn name(&self) -> &str {
|
||||
"url"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("url")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Apply url function"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
_args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
|
||||
Ok(OutputStream::one(ReturnSuccess::value(
|
||||
UntaggedValue::string(crate::commands::help::get_help(&Url, ®istry))
|
||||
.into_value(Tag::unknown()),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::Url;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(Url {})
|
||||
}
|
||||
}
|
58
crates/nu-cli/src/commands/url_/host.rs
Normal file
58
crates/nu-cli/src/commands/url_/host.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use url::Url;
|
||||
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct UrlHost;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for UrlHost {
|
||||
fn name(&self) -> &str {
|
||||
"url host"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("url host")
|
||||
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the host of a url"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &host).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![Example {
|
||||
description: "Get host of a url",
|
||||
example: "echo 'http://www.example.com/foo/bar' | url host",
|
||||
result: Some(vec![Value::from("www.example.com")]),
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
fn host(url: &Url) -> &str {
|
||||
url.host_str().unwrap_or("")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::UrlHost;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(UrlHost {})
|
||||
}
|
||||
}
|
72
crates/nu-cli/src/commands/url_/mod.rs
Normal file
72
crates/nu-cli/src/commands/url_/mod.rs
Normal file
@ -0,0 +1,72 @@
|
||||
mod command;
|
||||
mod host;
|
||||
mod path;
|
||||
mod query;
|
||||
mod scheme;
|
||||
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, Primitive, ReturnSuccess, ShellTypeName, UntaggedValue, Value};
|
||||
use url::Url;
|
||||
|
||||
pub use command::Url as UrlCommand;
|
||||
pub use host::UrlHost;
|
||||
pub use path::UrlPath;
|
||||
pub use query::UrlQuery;
|
||||
pub use scheme::UrlScheme;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct DefaultArguments {
|
||||
rest: Vec<ColumnPath>,
|
||||
}
|
||||
|
||||
fn handle_value<F>(action: &F, v: &Value) -> Result<Value, ShellError>
|
||||
where
|
||||
F: Fn(&Url) -> &str + Send + 'static,
|
||||
{
|
||||
let a = |url| UntaggedValue::string(action(url));
|
||||
let v = match &v.value {
|
||||
UntaggedValue::Primitive(Primitive::String(s))
|
||||
| UntaggedValue::Primitive(Primitive::Line(s)) => match Url::parse(s) {
|
||||
Ok(url) => a(&url).into_value(v.tag()),
|
||||
Err(_) => UntaggedValue::string("").into_value(v.tag()),
|
||||
},
|
||||
other => {
|
||||
let got = format!("got {}", other.type_name());
|
||||
return Err(ShellError::labeled_error(
|
||||
"value is not a string",
|
||||
got,
|
||||
v.tag().span,
|
||||
));
|
||||
}
|
||||
};
|
||||
Ok(v)
|
||||
}
|
||||
|
||||
async fn operate<F>(
|
||||
input: crate::InputStream,
|
||||
paths: Vec<ColumnPath>,
|
||||
action: &'static F,
|
||||
) -> Result<OutputStream, ShellError>
|
||||
where
|
||||
F: Fn(&Url) -> &str + Send + Sync + 'static,
|
||||
{
|
||||
Ok(input
|
||||
.map(move |v| {
|
||||
if paths.is_empty() {
|
||||
ReturnSuccess::value(handle_value(&action, &v)?)
|
||||
} else {
|
||||
let mut ret = v;
|
||||
|
||||
for path in &paths {
|
||||
ret = ret.swap_data_by_column_path(
|
||||
path,
|
||||
Box::new(move |old| handle_value(&action, &old)),
|
||||
)?;
|
||||
}
|
||||
|
||||
ReturnSuccess::value(ret)
|
||||
}
|
||||
})
|
||||
.to_output_stream())
|
||||
}
|
61
crates/nu-cli/src/commands/url_/path.rs
Normal file
61
crates/nu-cli/src/commands/url_/path.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use url::Url;
|
||||
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct UrlPath;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for UrlPath {
|
||||
fn name(&self) -> &str {
|
||||
"url path"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("url path")
|
||||
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the path of a url"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &Url::path).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Get path of a url",
|
||||
example: "echo 'http://www.example.com/foo/bar' | url path",
|
||||
result: Some(vec![Value::from("/foo/bar")]),
|
||||
},
|
||||
Example {
|
||||
description: "A trailing slash will be reflected in the path",
|
||||
example: "echo 'http://www.example.com' | url path",
|
||||
result: Some(vec![Value::from("/")]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::UrlPath;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(UrlPath {})
|
||||
}
|
||||
}
|
65
crates/nu-cli/src/commands/url_/query.rs
Normal file
65
crates/nu-cli/src/commands/url_/query.rs
Normal file
@ -0,0 +1,65 @@
|
||||
use url::Url;
|
||||
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct UrlQuery;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for UrlQuery {
|
||||
fn name(&self) -> &str {
|
||||
"url query"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("url query")
|
||||
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the query of a url"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &query).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Get query of a url",
|
||||
example: "echo 'http://www.example.com/?foo=bar&baz=quux' | url query",
|
||||
result: Some(vec![Value::from("foo=bar&baz=quux")]),
|
||||
},
|
||||
Example {
|
||||
description: "No query gives the empty string",
|
||||
example: "echo 'http://www.example.com/' | url query",
|
||||
result: Some(vec![Value::from("")]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
fn query(url: &Url) -> &str {
|
||||
url.query().unwrap_or("")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::UrlQuery;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(UrlQuery {})
|
||||
}
|
||||
}
|
60
crates/nu-cli/src/commands/url_/scheme.rs
Normal file
60
crates/nu-cli/src/commands/url_/scheme.rs
Normal file
@ -0,0 +1,60 @@
|
||||
use url::Url;
|
||||
|
||||
use super::{operate, DefaultArguments};
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{Signature, SyntaxShape, Value};
|
||||
|
||||
pub struct UrlScheme;
|
||||
|
||||
#[async_trait]
|
||||
impl WholeStreamCommand for UrlScheme {
|
||||
fn name(&self) -> &str {
|
||||
"url scheme"
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("url scheme").rest(SyntaxShape::ColumnPath, "optionally operate by path")
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"gets the scheme (eg http, file) of a url"
|
||||
}
|
||||
|
||||
async fn run(
|
||||
&self,
|
||||
args: CommandArgs,
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let (DefaultArguments { rest }, input) = args.process(®istry).await?;
|
||||
operate(input, rest, &Url::scheme).await
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Get scheme of a url",
|
||||
example: "echo 'http://www.example.com' | url scheme",
|
||||
result: Some(vec![Value::from("http")]),
|
||||
},
|
||||
Example {
|
||||
description: "You get an empty string if there is no scheme",
|
||||
example: "echo 'test' | url scheme",
|
||||
result: Some(vec![Value::from("")]),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::UrlScheme;
|
||||
|
||||
#[test]
|
||||
fn examples_work_as_expected() {
|
||||
use crate::examples::test as test_examples;
|
||||
|
||||
test_examples(UrlScheme {})
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user