Skip to content

Commit 241caaf

Browse files
authored
Add CLI option -f, --file to read from file (#12)
`-` will act like an alias for `-f -`
1 parent 0f4b231 commit 241caaf

File tree

7 files changed

+64
-40
lines changed

7 files changed

+64
-40
lines changed

Cargo.lock

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "jf"
3-
version = "0.6.0"
3+
version = "0.6.1"
44
edition = "2021"
55
authors = ["Arijit Basu <[email protected]>"]
66
description = 'A small utility to safely format and print JSON objects in the commandline'

README.md

+12-12
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,25 @@ nix-env -f https://github.com/NixOS/nixpkgs/tarball/nixos-unstable -iA jf
4343
### USAGE
4444

4545
```bash
46-
jf [OPTION]... [--] TEMPLATE [VALUE]... [NAME=VALUE]... [NAME@FILE]...
46+
jf [OPTION]... [--] TEMPLATE [VALUE]... [NAME=VALUE]... [NAME@FILE]...
4747
```
4848

4949
### OPTIONS
5050

51-
| option | help |
52-
| ------------- | ----------------------------------------------- |
53-
| - | pass template via stdin |
54-
| -- | stop parsing CLI options |
55-
| -r, --raw | print the raw rendered value without formatting |
56-
| -p, --pretty | pretty print the JSON formatted output |
57-
| -y, --yaml | print the output as YAML instead of JSON |
58-
| -h, --help | print this help message |
59-
| -v, --version | print the version number |
51+
| option | help |
52+
| ------------- | -------------------------------------------------- |
53+
| - | alias for `-f -`, i.e. read template from stdin |
54+
| -- | stop parsing CLI options |
55+
| -r, --raw | print the raw rendered value without formatting |
56+
| -p, --pretty | pretty print the JSON formatted output |
57+
| -y, --yaml | print the output as YAML instead of JSON |
58+
| -h, --help | print this help message |
59+
| -v, --version | print the version number |
60+
| -f, --file | treat the template argument as a file to read from |
6061

6162
### TEMPLATE
6263

63-
A template is a string that should render into valid YAML. It can contain the
64-
following placeholders:
64+
Template should render into valid YAML. It can contain the following placeholders:
6565

6666
- `%%` a literal `%` character
6767
- `%s` `%q` read positional argument

assets/jf.1

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jf [OPTION]\.\.\. [--] TEMPLATE [VALUE]\.\.\. [NAME=VALUE]\.\.\. [NAME@FILE]\.\.
88
.TP
99
.B
1010
-
11-
pass template via stdin
11+
alias for `\fB-f\fP -`, i.e. read template from stdin
1212
.TP
1313
.B
1414
--
@@ -33,10 +33,13 @@ print this help message
3333
.B
3434
\fB-v\fP, \fB--version\fP
3535
print the version number
36+
.TP
37+
.B
38+
\fB-f\fP, \fB--file\fP
39+
treat the template argument as a file to read from
3640
.SH TEMPLATE
3741

38-
A template is a string that should render into valid YAML. It can contain the
39-
following placeholders:
42+
Template should render into valid YAML. It can contain the following placeholders:
4043
.TP
4144
.B
4245
`%%`

src/cli.rs

+39-18
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate as jf;
22
use crate::VERSION;
33
use std::env::Args;
4-
use std::io;
5-
use std::iter::{Peekable, Skip};
4+
use std::iter::Skip;
5+
use std::{fs, io};
66

77
#[derive(Debug)]
88
pub enum Format {
@@ -16,60 +16,81 @@ pub enum Format {
1616
pub enum Cli {
1717
Help,
1818
Version,
19-
Format(Format, Peekable<Skip<Args>>),
19+
Format(Format, Option<String>, Skip<Args>),
2020
}
2121

2222
impl Cli {
23-
pub fn parse() -> Result<Self, jf::Error> {
23+
pub fn parse() -> jf::Result<Self> {
2424
let mut format = Format::Json;
25-
let mut args = std::env::args().skip(1).peekable();
25+
let mut template: Option<String> = None;
26+
let mut args = std::env::args().skip(1);
27+
let mut is_file = false;
2628

27-
while let Some(arg) = args.peek_mut() {
29+
while let Some(arg) = args.next() {
2830
match arg.as_str() {
2931
"-h" | "--help" => return Ok(Self::Help),
3032
"-v" | "--version" => return Ok(Self::Version),
3133
"-r" | "--raw" => {
3234
format = Format::Raw;
33-
args.next();
3435
}
3536
"-p" | "--pretty" => {
3637
format = Format::PrettyJson;
37-
args.next();
3838
}
3939
"-y" | "--yaml" => {
4040
format = Format::Yaml;
41-
args.next();
41+
}
42+
"-f" | "--file" => {
43+
is_file = true;
4244
}
4345
"-" => {
44-
*arg = io::read_to_string(io::stdin().lock())?;
46+
is_file = false;
47+
template = Some(io::read_to_string(io::stdin().lock())?);
4548
break;
4649
}
4750
"--" => {
48-
args.next();
4951
break;
5052
}
5153
a if a.starts_with('-') => {
5254
return Err(format!("invalid argument {a}, try -h or --help")
5355
.as_str()
5456
.into())
5557
}
56-
_ => break,
58+
_ => {
59+
template = Some(arg);
60+
break;
61+
}
5762
}
5863
}
5964

60-
Ok(Self::Format(format, args))
65+
if template.is_none() {
66+
template = args.next()
67+
}
68+
69+
if is_file {
70+
if let Some(tmpl) = template.as_mut() {
71+
*tmpl = fs::read_to_string(&tmpl)?;
72+
}
73+
}
74+
75+
Ok(Self::Format(format, template, args))
6176
}
6277

6378
pub fn process(self) -> Result<String, jf::Error> {
6479
match self {
6580
Self::Help => Ok(jf::USAGE.into()),
6681
Self::Version => Ok(format!("jf {VERSION}")),
67-
Self::Format(Format::Raw, args) => jf::render(args.map(Into::into)),
68-
Self::Format(Format::Json, args) => jf::format(args.map(Into::into)),
69-
Self::Format(Format::PrettyJson, args) => {
70-
jf::format_pretty(args.map(Into::into))
82+
Self::Format(Format::Raw, template, args) => {
83+
jf::render(template.iter().map(Into::into).chain(args.map(Into::into)))
84+
}
85+
Self::Format(Format::Json, template, args) => {
86+
jf::format(template.iter().map(Into::into).chain(args.map(Into::into)))
7187
}
72-
Self::Format(Format::Yaml, args) => jf::format_yaml(args.map(Into::into)),
88+
Self::Format(Format::PrettyJson, template, args) => jf::format_pretty(
89+
template.iter().map(Into::into).chain(args.map(Into::into)),
90+
),
91+
Self::Format(Format::Yaml, template, args) => jf::format_yaml(
92+
template.iter().map(Into::into).chain(args.map(Into::into)),
93+
),
7394
}
7495
}
7596
}

src/lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
/// To handle also the CLI options, use the `jf::cli` module.
66
pub mod cli;
77
pub mod error;
8+
pub use error::{Error, Result};
89
pub use serde_json as json;
910
pub use serde_yaml as yaml;
1011

11-
use crate::error::{Error, Result};
1212
use std::io::BufRead;
1313
use std::{borrow::Cow, collections::HashMap};
1414
use std::{fs, io};
1515

1616
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
17-
pub const USAGE: &str = include_str!("./usage.txt");
17+
pub const USAGE: &str = include_str!("usage.txt");
1818

1919
fn read_to_string<S>(path: &str, stdin: &mut S) -> Result<String>
2020
where

src/usage.txt

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@ USAGE
44

55
OPTIONS
66

7-
- pass template via stdin
7+
- alias for `-f -`, i.e. read template from stdin
88
-- stop parsing CLI options
99
-r, --raw print the raw rendered value without formatting
1010
-p, --pretty pretty print the JSON formatted output
1111
-y, --yaml print the output as YAML instead of JSON
1212
-h, --help print this help message
1313
-v, --version print the version number
14+
-f, --file treat the template argument as a file to read from
1415

1516
TEMPLATE
1617

17-
A template is a string that should render into valid YAML. It can contain the
18-
following placeholders:
18+
Template should render into valid YAML. It can contain the following placeholders:
1919

2020
`%%` a literal `%` character
2121
`%s` `%q` read positional argument

0 commit comments

Comments
 (0)