improve completion generation/binary usage

This commit is contained in:
askiiart 2025-01-30 12:07:21 -06:00
parent a4bcaf6103
commit b440555138
Signed by untrusted user who does not match committer: askiiart
GPG key ID: 6A32977DAF31746A
4 changed files with 58 additions and 48 deletions

View file

@ -50,6 +50,18 @@ let decoded = decode(encoded);
assert_eq!(decoded, "i love cats"); assert_eq!(decoded, "i love cats");
``` ```
Or to encode binary in cat2text's expanded base16 alphabet:
```rust
use cat2text::{anybase::bytes::encode, core::bytes::char_length};
let bytes = &[243, 10];
let base = 16;
let char_length = char_length(base);
assert_eq!("mrow~ mrow meow purrrr", encode(bytes, base, char_length));
```
You can use the library to encode anything up to base 16 - for details, see the [docs](https://docs.rs/cat2text/latest/cat2text/) You can use the library to encode anything up to base 16 - for details, see the [docs](https://docs.rs/cat2text/latest/cat2text/)
## Binary usage ## Binary usage
@ -92,12 +104,3 @@ For example, `cat2text encode 'i love cats'` to encode `i love cats` in text mod
### Shell completions ### Shell completions
To generate shell completions, you can run `cat2text generate-$(basename $SHELL)-completions | source` on *nix systems using bash, zsh, or fish. To generate shell completions, you can run `cat2text generate-$(basename $SHELL)-completions | source` on *nix systems using bash, zsh, or fish.
## Limitations
This currently only supports lowercase text in the latin alphabet, and byte arrays.
## TODO
- Add error handling
- Optimize code

View file

@ -19,7 +19,8 @@ pub fn encode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
shortened_alphabet.truncate(base as usize); shortened_alphabet.truncate(base as usize);
// makes it lowercase and split by spaces // makes it lowercase and split by spaces
let words: Vec<String> = text.as_ref() let words: Vec<String> = text
.as_ref()
.to_ascii_lowercase() .to_ascii_lowercase()
.split(" ") .split(" ")
.map(|item| return item.to_string()) .map(|item| return item.to_string())
@ -61,7 +62,11 @@ pub fn encode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
/// assert_eq!("i love cats", decode(text, base, char_length)); /// assert_eq!("i love cats", decode(text, base, char_length));
/// ``` /// ```
pub fn decode(text: impl AsRef<str>, base: u32, char_length: u32) -> String { pub fn decode(text: impl AsRef<str>, base: u32, char_length: u32) -> String {
let catspeak_words: Vec<String> = text.as_ref().split("; ").map(|item| item.to_string()).collect(); let catspeak_words: Vec<String> = text
.as_ref()
.split("; ")
.map(|item| item.to_string())
.collect();
let mut output: String = String::new(); let mut output: String = String::new();
let mut shortened_alphabet = core::alphabet(); let mut shortened_alphabet = core::alphabet();
shortened_alphabet.truncate(base as usize); shortened_alphabet.truncate(base as usize);

View file

@ -1,7 +1,7 @@
// this is a separate feature for *optional* dependencies to ensure clap doesn't get compiled if you're just using the library // this is a separate feature for *optional* dependencies to ensure clap doesn't get compiled if you're just using the library
use cat2text::{self, anybase, core}; use cat2text::{self, anybase, core};
use clap::{CommandFactory, Parser, Subcommand}; use clap::{CommandFactory, Parser, Subcommand};
use clap_complete::aot::{generate, Bash, Fish, PowerShell, Zsh}; use clap_complete::aot::{generate, Bash, Elvish, Fish, PowerShell, Zsh};
use std::{io::stdout, time::Instant}; use std::{io::stdout, time::Instant};
#[derive(Parser)] #[derive(Parser)]
@ -13,14 +13,13 @@ pub(crate) struct Cli {
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
pub(crate) enum Commands { pub(crate) enum Commands {
///Generate bash completions ///Generate shell completions
GenerateBashCompletions, GenCompletion {
///Generate zsh completions #[command(subcommand)]
GenerateZshCompletions, shell: ShellCommands,
///Generate fish completions #[arg(short, long, default_value = "cat2text")]
GenerateFishCompletions, binary_name: String,
///Generate PowerShell completions, },
GeneratePowershellCompletions,
///Encodes text/data to mrow~ ///Encodes text/data to mrow~
/// ///
///The default is base 4 text encoding, to match the original program, but it can encode either text or binary data in up to base 16 meows :3 ///The default is base 4 text encoding, to match the original program, but it can encode either text or binary data in up to base 16 meows :3
@ -63,33 +62,23 @@ pub(crate) fn run() {
let cli = Cli::parse(); let cli = Cli::parse();
match cli.command { match cli.command {
Commands::GenerateBashCompletions => { Commands::GenCompletion { shell, binary_name } => match shell {
generate( ShellCommands::Bash => {
Bash, generate(Bash, &mut Cli::command(), binary_name, &mut stdout());
&mut Cli::command(), }
clap::crate_name!(), ShellCommands::Zsh => {
&mut stdout(), generate(Zsh, &mut Cli::command(), binary_name, &mut stdout());
); }
} ShellCommands::Fish => {
Commands::GenerateZshCompletions => { generate(Fish, &mut Cli::command(), binary_name, &mut stdout());
generate(Zsh, &mut Cli::command(), clap::crate_name!(), &mut stdout()); }
} ShellCommands::Elvish => {
Commands::GenerateFishCompletions => { generate(Elvish, &mut Cli::command(), binary_name, &mut stdout());
generate( }
Fish, ShellCommands::Powershell => {
&mut Cli::command(), generate(PowerShell, &mut Cli::command(), binary_name, &mut stdout());
clap::crate_name!(), }
&mut stdout(), },
);
}
Commands::GeneratePowershellCompletions => {
generate(
PowerShell,
&mut Cli::command(),
clap::crate_name!(),
&mut stdout(),
);
}
Commands::Encode { base, text, bytes } => { Commands::Encode { base, text, bytes } => {
println!("{}", encode(base, text, bytes)) println!("{}", encode(base, text, bytes))
} }
@ -160,3 +149,12 @@ fn decode(base: u8, text: String, bytes: bool) -> String {
} }
} }
} }
#[derive(Subcommand, Debug)]
pub enum ShellCommands {
Bash,
Zsh,
Fish,
Elvish,
Powershell,
}

View file

@ -70,7 +70,11 @@ pub fn cat_to_num(text: Vec<String>, alphabet: Vec<String>, char_length: u32) ->
pub(crate) fn split_every_x(text: impl AsRef<str>, x: u32) -> Vec<String> { pub(crate) fn split_every_x(text: impl AsRef<str>, x: u32) -> Vec<String> {
let x = x as usize; let x = x as usize;
let delim = " "; let delim = " ";
let tmp: Vec<String> = text.as_ref().split(delim).map(|item| item.to_string()).collect(); let tmp: Vec<String> = text
.as_ref()
.split(delim)
.map(|item| item.to_string())
.collect();
let mut output: Vec<String> = Vec::new(); let mut output: Vec<String> = Vec::new();
for i in 0..tmp.len() { for i in 0..tmp.len() {
if i % x == 0 { if i % x == 0 {