mirror of
https://github.com/nushell/nushell.git
synced 2025-04-22 20:28:22 +02:00
parent
37f10cf273
commit
26e77a4b05
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -2584,6 +2584,7 @@ dependencies = [
|
|||||||
"typetag",
|
"typetag",
|
||||||
"umask",
|
"umask",
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
|
"url",
|
||||||
"users",
|
"users",
|
||||||
"uuid",
|
"uuid",
|
||||||
"which",
|
"which",
|
||||||
|
@ -94,6 +94,7 @@ rayon = "1.3.1"
|
|||||||
starship = {version = "0.43.0", optional = true}
|
starship = {version = "0.43.0", optional = true}
|
||||||
trash = {version = "1.0.1", optional = true}
|
trash = {version = "1.0.1", optional = true}
|
||||||
quick-xml = "0.18.1"
|
quick-xml = "0.18.1"
|
||||||
|
url = {version = "2.1.1"}
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
users = "0.10.0"
|
users = "0.10.0"
|
||||||
|
@ -420,6 +420,12 @@ pub fn create_default_context(
|
|||||||
whole_stream_command(PathExpand),
|
whole_stream_command(PathExpand),
|
||||||
whole_stream_command(PathExists),
|
whole_stream_command(PathExists),
|
||||||
whole_stream_command(PathType),
|
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")]
|
#[cfg(feature = "clipboard")]
|
||||||
|
@ -115,6 +115,7 @@ pub(crate) mod to_yaml;
|
|||||||
pub(crate) mod trim;
|
pub(crate) mod trim;
|
||||||
pub(crate) mod uniq;
|
pub(crate) mod uniq;
|
||||||
pub(crate) mod update;
|
pub(crate) mod update;
|
||||||
|
pub(crate) mod url_;
|
||||||
pub(crate) mod version;
|
pub(crate) mod version;
|
||||||
pub(crate) mod what;
|
pub(crate) mod what;
|
||||||
pub(crate) mod where_;
|
pub(crate) mod where_;
|
||||||
@ -247,6 +248,7 @@ pub(crate) use to_yaml::ToYAML;
|
|||||||
pub(crate) use touch::Touch;
|
pub(crate) use touch::Touch;
|
||||||
pub(crate) use trim::Trim;
|
pub(crate) use trim::Trim;
|
||||||
pub(crate) use uniq::Uniq;
|
pub(crate) use uniq::Uniq;
|
||||||
|
pub(crate) use url_::{UrlCommand, UrlHost, UrlPath, UrlQuery, UrlScheme};
|
||||||
pub(crate) use version::Version;
|
pub(crate) use version::Version;
|
||||||
pub(crate) use what::What;
|
pub(crate) use what::What;
|
||||||
pub(crate) use where_::Where;
|
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