Skip to content

Commit

Permalink
Bring back 'bridge add' command
Browse files Browse the repository at this point in the history
  • Loading branch information
nilclass committed Jan 13, 2024
1 parent f0b4cac commit fb8ed3c
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 10 deletions.
28 changes: 26 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,30 @@ $ jlctl list-ports
╰──────────────┴───────────┴───────────────────╯
```

### Help
If you see a port with role "JumperlessPrimary", you're good to go.


Connect some rows together:
```
$ jlctl bridge set 3-7,14-2
```

Rows 3, 7, 14 and 2 should be lit up on your board now.

Retrieve the current list of bridges:
```
$ jlctl bridge list
3-7,14-2
```

Retrieve the list of nets:
```
$ jlctl net list
```

### Built-in Help

Use the `help` command to get a list of commands and options:

```
$ jlctl help
Expand All @@ -66,7 +89,7 @@ Options:
-V, --version Print version
```

To get help for a subcommand, run `jlctl help <command>`, e.g.
To get help for a specific command, run `jlctl help <command>`, e.g.
```
$ jlctl help bridge
Interact with bridges
Expand All @@ -83,6 +106,7 @@ Options:
-h, --help Print help
```

This works for subcommands as well:
```
$ jctl help bridge list
Download list of bridges from the Jumperless
Expand Down
91 changes: 83 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ enum Command {
Net(NetCommand),

/// Interact with bridges
///
/// A bridge is a connection between two nodes on the Jumperless.
#[command(subcommand, alias = "bridges")]
Bridge(BridgeCommand),

Expand Down Expand Up @@ -117,7 +119,7 @@ enum NetCommand {
output_format: OutputFormat,
},

/// Upload list of nets to the Jumperless
/// Upload list of nets (in JSON format) to the Jumperless
#[command()]
Send {
/// Read from file instead of stdin
Expand All @@ -142,15 +144,33 @@ enum BridgeCommand {
/// Write to file instead of stdout
#[arg(long, short)]
file: Option<String>,

/// Output format
#[arg(long, short, value_enum, default_value = "list")]
output_format: BridgeOutputFormat,
},

/// Upload new list of bridges to the Jumperless
///
/// Either `--file` or `--bridges` must be specified (but not both).
/// Either `--file` or `[bridges]` must be specified (but not both).
#[command()]
Set {
/// Bridge(s) to add, e.g. "GND-17" or "12-17,14-29"
#[arg()]
bridges: Option<String>,

/// Read bridges from file
#[arg(long, short)]
file: Option<String>,
},

/// Add one or more bridges to the current netlist
///
/// Either `--file` or `[bridges]` must be specified (but not both).
#[command()]
Add {
/// Bridge(s) to add, e.g. "GND-17" or "12-17,14-29"
#[arg()]
bridges: Option<String>,

/// Read bridges from file
Expand All @@ -163,6 +183,14 @@ enum BridgeCommand {
Clear,
}

#[derive(ValueEnum, Copy, Clone, PartialEq, Debug)]
enum BridgeOutputFormat {
#[value()]
List,
#[value()]
Json,
}

fn main() -> anyhow::Result<()> {
env_logger::init_from_env(Env::default().default_filter_or("info"));

Expand Down Expand Up @@ -291,22 +319,35 @@ fn main() -> anyhow::Result<()> {
},

Command::Bridge(bridge_command) => match bridge_command {
BridgeCommand::List { file } => {
BridgeCommand::List { file, output_format } => {
let mut output = file_or_stdout(file)?;
let bridgelist = device.bridgelist()?;
serde_json::to_writer_pretty(&mut output, &bridgelist)?;
output.write_all(b"\n")?;
match output_format {
BridgeOutputFormat::List => {
for (i, (a, b)) in bridgelist.into_iter().enumerate() {
if i > 0 {
write!(&mut output, ",")?;
}
write!(&mut output, "{}-{}", a, b)?;
}
output.write_all(b"\n")?;
}
BridgeOutputFormat::Json => {
serde_json::to_writer_pretty(&mut output, &bridgelist)?;
output.write_all(b"\n")?;
}
}
}
BridgeCommand::Set { bridges, file } => {
let source = match (bridges, file) {
(None, None) => {
return Err(anyhow::anyhow!(
"Either `--bridges` or `--file` must be given"
"Either `[bridges]` or `--file` must be given"
))
}
(Some(_), Some(_)) => {
return Err(anyhow::anyhow!(
"Cannot accept `--bridges` together with `--file`"
"Cannot accept `[bridges]` together with `--file`"
))
}
(Some(bridges), _) => bridges,
Expand All @@ -323,7 +364,41 @@ fn main() -> anyhow::Result<()> {
};
device.set_bridgelist(bridgelist)?;
}
_ => todo!(),
BridgeCommand::Add { bridges, file } => {
let source = match (bridges, file) {
(None, None) => {
return Err(anyhow::anyhow!(
"Either `[bridges]` or `--file` must be given"
))
}
(Some(_), Some(_)) => {
return Err(anyhow::anyhow!(
"Cannot accept `[bridges]` together with `--file`"
))
}
(Some(bridges), _) => bridges,
(_, Some(file)) => std::fs::read_to_string(file)?,
};

let bridgelist = if source.starts_with('[') {
serde_json::from_str(&source).expect("parse bridgelist as JSON")
} else {
let (_, bridgelist) =
nom::combinator::all_consuming(parser::bridges)(&source)
.expect("parse bridgelist");
bridgelist
};
let mut combined = device.bridgelist()?;
for bridge in bridgelist {
if !combined.contains(&bridge) {
combined.push(bridge);
}
}
device.set_bridgelist(combined)?;
}
BridgeCommand::Clear => {
device.set_bridgelist(vec![])?;
}
},
_ => unreachable!(),
}
Expand Down

0 comments on commit fb8ed3c

Please sign in to comment.