Requires N:M mapping

This mapping has 91 all-to-all groups: every node on one side corresponds to every node on the other, and none is deleted or inserted. Each member carries an all N:M badge; selecting one highlights all of its counterparts, in the tree and in the code view alike.

Code view:

A painting is a person's account of this edit as text, recorded independently of the node mapping - a rendering often has several equally defensible answers where the mapping has one. Deletions and insertions carry no position on the opposite side in a painting, so that panel draws no caret for them.

Before

1mod config;
2mod error;
3mod pokemon;
4
5use config::Config;
6use error::Error;
7use pokemon::*;
8
9use clap::{Args, Parser, Subcommand};
10use rand::seq::SliceRandom;
11use rand::Rng;
12use rust_embed::RustEmbed;
13
14use std::str;
15
16/// Print pokemon sprites in your terminal
17#[derive(Parser, Debug)]
18#[clap(author, version, about, long_about = None)]
19struct Cli {
20 #[clap(subcommand)]
21 command: Commands,
22}
23
24#[derive(Debug, Subcommand)]
25enum Commands {
26 /// Print list of all pokemon
27 List,
28 /// Select pokemon by name. Generally spelled like in the games.
29 /// A few exceptions are nidoran-f, nidoran-m, mr-mime, farfetchd,
30 /// flabebe type-null etc. Perhaps grep the output of list if in doubt.
31 Name(Name),
32 /// Show a random pokemon. This command can optionally be followed by a
33 /// generation number or range (1-9) to show random pokemon from a specific
34 /// generation or range of generations. The generations can be provided as
35 /// a continuous range (eg. 1-3) or as a list of generations (1,3,6)
36 Random(Random),
37}
38
39#[derive(Debug, Args)]
40struct Name {
41 /// Name of the pokemon to show
42 name: String,
43
44 /// Show an alternative form of the pokemon. For example: mega, mega-x,
45 /// mega-y, gmax, alola, hisui, galar, paldea
46 #[clap(short, long, default_value = "regular")]
47 form: String,
48
49 /// Show the shiny version of the pokemon instead
50 #[clap(short, long)]
51 shiny: bool,
52
53 /// Print pokedex entry (if it exists)
54 #[clap(short, long)]
55 info: bool,
56
57 /// Do not display pokemon name
58 #[clap(long)]
59 no_title: bool,
60
61 /// Left padding
62 #[clap(long, default_value = "0")]
63 padding_left: usize,
64}
65
66#[derive(Debug, Args)]
67struct Random {
68 /// Generation number, range (1-9), or list of generations (1,3,6)
69 #[clap(default_value = "1-9")]
70 generations: String,
71
72 /// Print pokedex entry (if it exists)
73 #[clap(short, long)]
74 info: bool,
75
76 /// Show the shiny version of the pokemon instead
77 #[clap(short, long)]
78 shiny: bool,
79
80 /// Do not display pokemon name
81 #[clap(long)]
82 no_title: bool,
83
84 /// Do not show mega pokemon
85 #[clap(long)]
86 no_mega: bool,
87
88 /// Do not show gigantamax pokemon
89 #[clap(long)]
90 no_gmax: bool,
91
92 /// Do not show regional pokemon
93 #[clap(long)]
94 no_regional: bool,
95
96 /// Left padding
97 #[clap(long, default_value = "0")]
98 padding_left: usize,
99}
100
101#[derive(RustEmbed)]
102#[folder = "assets/"]
103struct Asset;
104
105fn list_pokemon_names(pokemon_db: Vec<Pokemon>) {
106 pokemon_db.iter().for_each(|p| println!("{}", p.slug));
107}
108
109fn show_pokemon_by_name(
110 name: &Name,
111 pokemon_db: Vec<Pokemon>,
112 config: &Config,
113) -> Result<(), Error> {
114 match pokemon_db.iter().find(|p| p.slug == name.name) {
115 Some(pokemon) => {
116 let slug = if name.form == "regular" {
117 name.name.clone()
118 } else {
119 format!("{}-{}", name.name, name.form)
120 };
121 let art_path = if name.shiny {
122 format!("colorscripts/shiny/{}", slug)
123 } else {
124 format!("colorscripts/regular/{}", slug)
125 };
126 let art = Asset::get(&art_path)
127 .unwrap_or_else(|| panic!("Could not read pokemon art of '{}'", slug))
128 .data;
129 let art = str::from_utf8(&art).expect("Invalid UTF-8 in pokemon art");
130 if !name.no_title {
131 let pokemon_name = match pokemon.name.get(&config.language) {
132 Some(n) => n,
133 None => return Err(Error::InvalidLanguage(config.language.clone())),
134 };
135 print!("{: <1$}{pokemon_name}", "", name.padding_left);
136 match name.form.as_str() {
137 "regular" => println!(),
138 other => println!(" ({other})"),
139 }
140 }
141 if name.info {
142 if let Some(description) = pokemon.desc.get(&config.language) {
143 description
144 .lines()
145 .for_each(|line| println!("{: <1$}{line}", "", name.padding_left))
146 }
147 }
148 println!();
149 art.lines()
150 .for_each(|line| println!("{: <1$}{line}", "", name.padding_left))
151 }
152 None => {
153 return Err(Error::InvalidPokemon(name.name.clone()));
154 }
155 }
156 Ok(())
157}
158
159fn show_random_pokemon(
160 random: &Random,
161 pokemon_db: Vec<Pokemon>,
162 config: &Config,
163) -> Result<(), Error> {
164 let (start_gen, end_gen) = match random.generations.split_once('-') {
165 Some(gens) => gens,
166 None => {
167 let gen_list = random.generations.split(',').collect::<Vec<_>>();
168 let gen = gen_list.choose(&mut rand::thread_rng()).unwrap();
169 (*gen, *gen)
170 }
171 };
172
173 let start_gen = start_gen.parse::<u8>();
174 let end_gen = end_gen.parse::<u8>();
175 let (start_gen, end_gen) = match (start_gen, end_gen) {
176 (Ok(s), Ok(e)) => (s, e),
177 _ => return Err(Error::InvalidGeneration(random.generations.clone())),
178 };
179
180 // Filter by generation
181 let pokemon = pokemon_db
182 .iter()
183 .filter(|p| start_gen <= p.gen && end_gen >= p.gen)
184 .collect::<Vec<_>>();
185
186 let pokemon = match pokemon.choose(&mut rand::thread_rng()) {
187 Some(p) => Ok(p),
188 None => Err(Error::InvalidGeneration(random.generations.clone())),
189 }?;
190
191 let mut forms = vec!["regular".to_string()];
192 forms.extend_from_slice(&pokemon.forms);
193 // Optional filters
194 if random.no_mega {
195 forms.retain(|f| !["mega", "mega-x", "mega-y"].contains(&f.as_str()));
196 }
197 if random.no_gmax {
198 forms.retain(|f| f.as_str() != "gmax");
199 }
200 if random.no_regional {
201 forms.retain(|f| !["alola", "galar", "hisui", "paldea"].contains(&f.as_str()));
202 }
203 // forms will never be empty, so safe to unwrap
204 let form = forms.choose(&mut rand::thread_rng()).unwrap();
205 let shiny = rand::thread_rng().gen_bool(config.shiny_rate) || random.shiny;
206
207 show_pokemon_by_name(
208 &Name {
209 name: pokemon.slug.clone(),
210 form: form.to_string(),
211 shiny,
212 info: random.info,
213 no_title: random.no_title,
214 padding_left: random.padding_left,
215 },
216 pokemon_db,
217 config,
218 )
219}
220
221fn main() -> Result<(), Error> {
222 let config = Config::load()?;
223 let pokemon_db = Asset::get("pokemon.json").expect("Could not read pokemond db file");
224 let pokemon = load_pokemon(&pokemon_db)?;
225 let args = Cli::parse();
226 match args.command {
227 Commands::List => list_pokemon_names(pokemon),
228 Commands::Name(name) => show_pokemon_by_name(&name, pokemon, &config)?,
229 Commands::Random(random) => show_random_pokemon(&random, pokemon, &config)?,
230 }
231 Ok(())
232}
233

After

1mod config;
2mod error;
3mod pokemon;
4
5use config::Config;
6use error::Error;
7use pokemon::*;
8
9use clap::{Args, Parser, Subcommand};
10use rust_embed::RustEmbed;
11
12use std::str;
13
14/// Print pokemon sprites in your terminal
15#[derive(Parser, Debug)]
16#[clap(author, version, about, long_about = None)]
17struct Cli {
18 #[clap(subcommand)]
19 command: Commands,
20}
21
22#[derive(Debug, Subcommand)]
23enum Commands {
24 /// Print list of all pokemon
25 List(List),
26 /// Select pokemon by name. Generally spelled like in the games.
27 /// A few exceptions are nidoran-f, nidoran-m, mr-mime, farfetchd,
28 /// flabebe type-null etc. Perhaps grep the output of list if in doubt.
29 Name(Name),
30 /// Show a random pokemon. This command can optionally be followed by a
31 /// generation number or range (1-9) to show random pokemon from a specific
32 /// generation or range of generations. The generations can be provided as
33 /// a continuous range (eg. 1-3) or as a list of generations (1,3,6)
34 Random(Random),
35}
36
37#[derive(Debug, Args)]
38struct CommonArgs {
39 /// Print pokedex entry (if it exists)
40 #[clap(short, long)]
41 info: bool,
42
43 /// Show the shiny version of the pokemon instead
44 #[clap(short, long)]
45 shiny: bool,
46
47 /// Do not display pokemon name
48 #[clap(long)]
49 no_title: bool,
50
51 /// Left padding
52 #[clap(long, default_value = "0")]
53 padding_left: usize,
54}
55
56#[derive(Debug, Args)]
57struct List {
58 /// Generation number, range (1-9), or list of generations (1,3,6)
59 #[clap(default_value = "1-9")]
60 generations: Generations,
61}
62
63#[derive(Debug, Args)]
64struct Name {
65 /// Name of the pokemon to show
66 name: String,
67
68 /// Show an alternative form of the pokemon. For example: mega, mega-x,
69 /// mega-y, gmax, alola, hisui, galar, paldea
70 #[clap(short, long, default_value = "regular", value_parser = Form::from_str)]
71 form: Form,
72
73 #[clap(flatten)]
74 common: CommonArgs,
75}
76
77#[derive(Debug, Args)]
78struct Random {
79 /// Generation number, range (1-9), or list of generations (1,3,6)
80 #[clap(default_value = "1-9")]
81 generations: Generations,
82
83 /// Do not show mega pokemon
84 #[clap(long)]
85 no_mega: bool,
86
87 /// Do not show gigantamax pokemon
88 #[clap(long)]
89 no_gmax: bool,
90
91 /// Do not show regional pokemon
92 #[clap(long)]
93 no_regional: bool,
94
95 /// Do not show any variant-form pokemon
96 #[clap(long)]
97 no_variant: bool,
98
99 #[clap(flatten)]
100 common: CommonArgs,
101}
102
103#[derive(RustEmbed)]
104#[folder = "assets/"]
105struct Asset;
106
107fn main() -> Result<(), Error> {
108 let config = Config::load()?;
109 let pokemon_db_file = Asset::get("pokemon.json").expect("Could not read pokemon db file");
110 let pokemon_db = PokemonDatabase::load(&pokemon_db_file, config)?;
111 let args = Cli::parse();
112 match args.command {
113 Commands::List(list_args) => pokemon_db.list_pokemon_names(list_args.generations),
114 Commands::Name(name) => pokemon_db.show_pokemon_by_name(&name)?,
115 Commands::Random(random) => pokemon_db.show_random_pokemon(&random)?,
116 }
117 Ok(())
118}
119

Before

source_file
mod_item
mod "mod"
identifier "config"
; ";"
mod_item
mod "mod"
identifier "error"
; ";"
mod_item
mod "mod"
identifier "pokemon"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "config"
:: "::"
identifier "Config"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "error"
:: "::"
identifier "Error"
; ";"
use_declaration
use "use"
use_wildcard
identifier "pokemon"
:: "::"
* "*"
; ";"
use_declaration
use "use"
scoped_use_list
identifier "clap"
:: "::"
use_list
{ "{"
identifier "Args"
, ","
identifier "Parser"
, ","
identifier "Subcommand"
} "}"
; ";"
use_declaration
use "use"
scoped_identifier
scoped_identifier
identifier "rand"
:: "::"
identifier "seq"
:: "::"
identifier "SliceRandom"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "rand"
:: "::"
identifier "Rng"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "rust_embed"
:: "::"
identifier "RustEmbed"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "std"
:: "::"
identifier "str"
; ";"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Print pokemon sprites in your terminal\n"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Parser"
, ","
identifier "Debug"
) ")"
] "]"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "author"
, ","
identifier "version"
, ","
identifier "about"
, ","
identifier "long_about"
= "="
identifier "None"
) ")"
] "]"
struct_item (+21 nodes collapsed)
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Subcommand"
) ")"
] "]"
enum_item
enum "enum"
type_identifier "Commands"
enum_variant_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Print list of all pokemon\n"
enum_variant
identifier "List"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Select pokemon by name. Generally spelled like in the games"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " A few exceptions are nidoran-f, nidoran-m, mr-mime, farfetc"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " flabebe type-null etc. Perhaps grep the output of list if i"...
enum_variant
identifier "Name"
ordered_field_declaration_list
( "("
type_identifier "Name"
) ")"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Show a random pokemon. This command can optionally be follo"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " generation number or range (1-9) to show random pokemon fro"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " generation or range of generations. The generations can be "...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " a continuous range (eg. 1-3) or as a list of generations (1"...
enum_variant
identifier "Random"
ordered_field_declaration_list
( "("
type_identifier "Random"
) ")"
, ","
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "Name"
field_declaration_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Name of the pokemon to show\n"
field_declaration
field_identifier "name"
: ":"
type_identifier "String"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Show an alternative form of the pokemon. For example: mega,"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " mega-y, gmax, alola, hisui, galar, paldea\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "short"
, ","
identifier "long"
, ","
identifier "default_value"
= "="
string_literal
" "\""
string_content "regular"
" "\""
) ")"
] "]"
field_declaration
field_identifier "form"
: ":"
type_identifier "String"
, ","
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Show the shiny version of the pokemon instead\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "shiny" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Print pokedex entry (if it exists)\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "info" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Do not display pokemon name\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "no_title" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Left padding\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
, "," all 2:1
identifier "default_value" all 2:1
= "=" all 2:1
string_literal all 2:1
" "\"" all 2:1
string_content "0" all 2:1
" "\"" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "padding_left" all 2:1
: ":" all 2:1
primitive_type "usize" all 2:1
, "," all 2:1
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "Random"
field_declaration_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Generation number, range (1-9), or list of generations (1,3"...
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "default_value"
= "="
string_literal
" "\""
string_content "1-9"
" "\""
) ")"
] "]"
field_declaration
field_identifier "generations"
: ":"
type_identifier "String"
, ","
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Print pokedex entry (if it exists)\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "info" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Show the shiny version of the pokemon instead\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "shiny" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Do not display pokemon name\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "no_title" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show mega pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_mega"
: ":"
primitive_type "bool"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show gigantamax pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_gmax"
: ":"
primitive_type "bool"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show regional pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_regional"
: ":"
primitive_type "bool"
, ","
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Left padding\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
, "," all 2:1
identifier "default_value" all 2:1
= "=" all 2:1
string_literal all 2:1
" "\"" all 2:1
string_content "0" all 2:1
" "\"" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "padding_left" all 2:1
: ":" all 2:1
primitive_type "usize" all 2:1
, "," all 2:1
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "RustEmbed"
) ")"
] "]"
attribute_item
# "#"
[ "["
attribute
identifier "folder"
= "="
string_literal
" "\""
string_content "assets/"
" "\""
] "]"
struct_item
struct "struct"
type_identifier "Asset"
; ";"
function_item
fn "fn"
identifier "list_pokemon_names"
parameters
( "("
parameter
identifier "pokemon_db"
: ":"
generic_type
type_identifier "Vec"
type_arguments
< "<"
type_identifier "Pokemon"
> ">"
) ")"
block
{ "{"
expression_statement
call_expression
field_expression
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "iter"
arguments
( "("
) ")"
. "."
field_identifier "for_each"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "p"
| "|"
macro_invocation
identifier "println"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "{}"
" "\""
, ","
identifier "p"
. "."
identifier "slug"
) ")"
) ")"
; ";"
} "}"
function_item
fn "fn"
identifier "show_pokemon_by_name"
parameters
( "("
parameter
identifier "name"
: ":"
reference_type
& "&"
type_identifier "Name"
, ","
parameter
identifier "pokemon_db"
: ":"
generic_type
type_identifier "Vec"
type_arguments
< "<"
type_identifier "Pokemon"
> ">"
, ","
parameter
identifier "config"
: ":"
reference_type
& "&"
type_identifier "Config"
, ","
) ")"
-> "->"
generic_type
type_identifier "Result"
type_arguments
< "<"
unit_type
( "("
) ")"
, ","
type_identifier "Error"
> ">"
block
{ "{"
expression_statement
match_expression
match "match"
call_expression
field_expression
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "iter"
arguments
( "("
) ")"
. "."
field_identifier "find"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "p"
| "|"
binary_expression
field_expression
identifier "p"
. "."
field_identifier "slug"
== "=="
field_expression
identifier "name"
. "."
field_identifier "name"
) ")"
match_block
{ "{"
match_arm
match_pattern
tuple_struct_pattern
identifier "Some"
( "("
identifier "pokemon"
) ")"
=> "=>"
block
{ "{"
let_declaration
let "let"
identifier "slug"
= "="
if_expression
if "if"
binary_expression
field_expression
identifier "name"
. "."
field_identifier "form"
== "=="
string_literal
" "\""
string_content "regular"
" "\""
block
{ "{"
call_expression
field_expression
field_expression
identifier "name"
. "."
field_identifier "name"
. "."
field_identifier "clone"
arguments
( "("
) ")"
} "}"
else_clause
else "else"
block
{ "{"
macro_invocation
identifier "format"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "{}-{}"
" "\""
, ","
identifier "name"
. "."
identifier "name"
, ","
identifier "name"
. "."
identifier "form"
) ")"
} "}"
; ";"
let_declaration
let "let"
identifier "art_path"
= "="
if_expression
if "if"
field_expression
identifier "name"
. "."
field_identifier "shiny"
block
{ "{"
macro_invocation
identifier "format"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "colorscripts/shiny/{}"
" "\""
, ","
identifier "slug"
) ")"
} "}"
else_clause
else "else"
block
{ "{"
macro_invocation
identifier "format"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "colorscripts/regular/{}"
" "\""
, ","
identifier "slug"
) ")"
} "}"
; ";"
let_declaration
let "let"
identifier "art"
= "="
field_expression
call_expression
field_expression
call_expression
scoped_identifier
identifier "Asset"
:: "::"
identifier "get"
arguments
( "("
reference_expression
& "&"
identifier "art_path"
) ")"
. "."
field_identifier "unwrap_or_else"
arguments
( "("
closure_expression
closure_parameters
| "|"
| "|"
macro_invocation
identifier "panic"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "Could not read pokemon art of '{}'"
" "\""
, ","
identifier "slug"
) ")"
) ")"
. "."
field_identifier "data"
; ";"
let_declaration
let "let"
identifier "art"
= "="
call_expression
field_expression
call_expression
scoped_identifier
identifier "str"
:: "::"
identifier "from_utf8"
arguments
( "("
reference_expression
& "&"
identifier "art"
) ")"
. "."
field_identifier "expect"
arguments
( "("
string_literal
" "\""
string_content "Invalid UTF-8 in pokemon art"
" "\""
) ")"
; ";"
expression_statement
if_expression
if "if"
unary_expression
! "!"
field_expression
identifier "name"
. "."
field_identifier "no_title"
block
{ "{"
let_declaration
let "let"
identifier "pokemon_name"
= "="
match_expression
match "match"
call_expression
field_expression
field_expression
identifier "pokemon"
. "."
field_identifier "name"
. "."
field_identifier "get"
arguments
( "("
reference_expression
& "&"
field_expression
identifier "config"
. "."
field_identifier "language"
) ")"
match_block
{ "{"
match_arm
match_pattern
tuple_struct_pattern
identifier "Some"
( "("
identifier "n"
) ")"
=> "=>"
identifier "n"
, ","
match_arm
match_pattern
identifier "None"
=> "=>"
return_expression
return "return"
call_expression
identifier "Err"
arguments
( "("
call_expression
scoped_identifier
identifier "Error"
:: "::"
identifier "InvalidLanguage"
arguments
( "("
call_expression
field_expression
field_expression
identifier "config"
. "."
field_identifier "language"
. "."
field_identifier "clone"
arguments
( "("
) ")"
) ")"
) ")"
, ","
} "}"
; ";"
expression_statement
macro_invocation
identifier "print"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "{: <1$}{pokemon_name}"
" "\""
, ","
string_literal
" "\""
" "\""
, ","
identifier "name"
. "."
identifier "padding_left"
) ")"
; ";"
expression_statement
match_expression
match "match"
call_expression
field_expression
field_expression
identifier "name"
. "."
field_identifier "form"
. "."
field_identifier "as_str"
arguments
( "("
) ")"
match_block
{ "{"
match_arm
match_pattern
string_literal
" "\""
string_content "regular"
" "\""
=> "=>"
macro_invocation
identifier "println"
! "!"
token_tree
( "("
) ")"
, ","
match_arm
match_pattern
identifier "other"
=> "=>"
macro_invocation
identifier "println"
! "!"
token_tree
( "("
string_literal
" "\""
string_content " ({other})"
" "\""
) ")"
, ","
} "}"
} "}"
expression_statement
if_expression
if "if"
field_expression
identifier "name"
. "."
field_identifier "info"
block
{ "{"
expression_statement
if_expression
if "if"
let_condition
let "let"
tuple_struct_pattern
identifier "Some"
( "("
identifier "description"
) ")"
= "="
call_expression
field_expression
field_expression
identifier "pokemon"
. "."
field_identifier "desc"
. "."
field_identifier "get"
arguments
( "("
reference_expression
& "&"
field_expression
identifier "config"
. "."
field_identifier "language"
) ")"
block
{ "{"
call_expression
field_expression
call_expression
field_expression
identifier "description"
. "."
field_identifier "lines"
arguments
( "("
) ")"
. "."
field_identifier "for_each"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "line"
| "|"
macro_invocation
identifier "println"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "{: <1$}{line}"
" "\""
, ","
string_literal
" "\""
" "\""
, ","
identifier "name"
. "."
identifier "padding_left"
) ")"
) ")"
} "}"
} "}"
expression_statement
macro_invocation
identifier "println"
! "!"
token_tree
( "("
) ")"
; ";"
call_expression
field_expression
call_expression
field_expression
identifier "art"
. "."
field_identifier "lines"
arguments
( "("
) ")"
. "."
field_identifier "for_each"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "line"
| "|"
macro_invocation
identifier "println"
! "!"
token_tree
( "("
string_literal
" "\""
string_content "{: <1$}{line}"
" "\""
, ","
string_literal
" "\""
" "\""
, ","
identifier "name"
. "."
identifier "padding_left"
) ")"
) ")"
} "}"
match_arm
match_pattern
identifier "None"
=> "=>"
block
{ "{"
expression_statement
return_expression
return "return"
call_expression
identifier "Err"
arguments
( "("
call_expression
scoped_identifier
identifier "Error"
:: "::"
identifier "InvalidPokemon"
arguments
( "("
call_expression
field_expression
field_expression
identifier "name"
. "."
field_identifier "name"
. "."
field_identifier "clone"
arguments
( "("
) ")"
) ")"
) ")"
; ";"
} "}"
} "}"
call_expression
identifier "Ok"
arguments
( "("
unit_expression
( "("
) ")"
) ")"
} "}"
function_item
fn "fn"
identifier "show_random_pokemon"
parameters
( "("
parameter
identifier "random"
: ":"
reference_type
& "&"
type_identifier "Random"
, ","
parameter
identifier "pokemon_db"
: ":"
generic_type
type_identifier "Vec"
type_arguments
< "<"
type_identifier "Pokemon"
> ">"
, ","
parameter
identifier "config"
: ":"
reference_type
& "&"
type_identifier "Config"
, ","
) ")"
-> "->"
generic_type
type_identifier "Result"
type_arguments
< "<"
unit_type
( "("
) ")"
, ","
type_identifier "Error"
> ">"
block
{ "{"
let_declaration
let "let"
tuple_pattern
( "("
identifier "start_gen"
, ","
identifier "end_gen"
) ")"
= "="
match_expression
match "match"
call_expression
field_expression
field_expression
identifier "random"
. "."
field_identifier "generations"
. "."
field_identifier "split_once"
arguments
( "("
char_literal "'-'"
) ")"
match_block
{ "{"
match_arm
match_pattern
tuple_struct_pattern
identifier "Some"
( "("
identifier "gens"
) ")"
=> "=>"
identifier "gens"
, ","
match_arm
match_pattern
identifier "None"
=> "=>"
block
{ "{"
let_declaration
let "let"
identifier "gen_list"
= "="
call_expression
generic_function
field_expression
call_expression
field_expression
field_expression
identifier "random"
. "."
field_identifier "generations"
. "."
field_identifier "split"
arguments
( "("
char_literal "','"
) ")"
. "."
field_identifier "collect"
:: "::"
type_arguments
< "<"
generic_type
type_identifier "Vec"
type_arguments
< "<"
type_identifier "_"
> ">"
> ">"
arguments
( "("
) ")"
; ";"
let_declaration
let "let"
identifier "gen"
= "="
call_expression
field_expression
call_expression
field_expression
identifier "gen_list"
. "."
field_identifier "choose"
arguments
( "("
reference_expression
& "&"
mutable_specifier "mut"
call_expression
scoped_identifier
identifier "rand"
:: "::"
identifier "thread_rng"
arguments
( "("
) ")"
) ")"
. "."
field_identifier "unwrap"
arguments
( "("
) ")"
; ";"
tuple_expression
( "("
unary_expression
* "*"
identifier "gen"
, ","
unary_expression
* "*"
identifier "gen"
) ")"
} "}"
} "}"
; ";"
let_declaration
let "let"
identifier "start_gen"
= "="
call_expression
generic_function
field_expression
identifier "start_gen"
. "."
field_identifier "parse"
:: "::"
type_arguments
< "<"
primitive_type "u8"
> ">"
arguments
( "("
) ")"
; ";"
let_declaration
let "let"
identifier "end_gen"
= "="
call_expression
generic_function
field_expression
identifier "end_gen"
. "."
field_identifier "parse"
:: "::"
type_arguments
< "<"
primitive_type "u8"
> ">"
arguments
( "("
) ")"
; ";"
let_declaration
let "let"
tuple_pattern
( "("
identifier "start_gen"
, ","
identifier "end_gen"
) ")"
= "="
match_expression
match "match"
tuple_expression
( "("
identifier "start_gen"
, ","
identifier "end_gen"
) ")"
match_block
{ "{"
match_arm
match_pattern
tuple_pattern
( "("
tuple_struct_pattern
identifier "Ok"
( "("
identifier "s"
) ")"
, ","
tuple_struct_pattern
identifier "Ok"
( "("
identifier "e"
) ")"
) ")"
=> "=>"
tuple_expression
( "("
identifier "s"
, ","
identifier "e"
) ")"
, ","
match_arm
match_pattern
_ "_"
=> "=>"
return_expression
return "return"
call_expression
identifier "Err"
arguments
( "("
call_expression
scoped_identifier
identifier "Error"
:: "::"
identifier "InvalidGeneration"
arguments
( "("
call_expression
field_expression
field_expression
identifier "random"
. "."
field_identifier "generations"
. "."
field_identifier "clone"
arguments
( "("
) ")"
) ")"
) ")"
, ","
} "}"
; ";"
line_comment
// "//"
let_declaration
let "let"
identifier "pokemon"
= "="
call_expression
generic_function
field_expression
call_expression
field_expression
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "iter"
arguments
( "("
) ")"
. "."
field_identifier "filter"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "p"
| "|"
binary_expression
binary_expression
identifier "start_gen"
<= "<="
field_expression
identifier "p"
. "."
field_identifier "gen"
&& "&&"
binary_expression
identifier "end_gen"
>= ">="
field_expression
identifier "p"
. "."
field_identifier "gen"
) ")"
. "."
field_identifier "collect"
:: "::"
type_arguments
< "<"
generic_type
type_identifier "Vec"
type_arguments
< "<"
type_identifier "_"
> ">"
> ">"
arguments
( "("
) ")"
; ";"
let_declaration
let "let"
identifier "pokemon"
= "="
try_expression
match_expression
match "match"
call_expression
field_expression
identifier "pokemon"
. "."
field_identifier "choose"
arguments
( "("
reference_expression
& "&"
mutable_specifier "mut"
call_expression
scoped_identifier
identifier "rand"
:: "::"
identifier "thread_rng"
arguments
( "("
) ")"
) ")"
match_block
{ "{"
match_arm
match_pattern
tuple_struct_pattern
identifier "Some"
( "("
identifier "p"
) ")"
=> "=>"
call_expression
identifier "Ok"
arguments
( "("
identifier "p"
) ")"
, ","
match_arm
match_pattern
identifier "None"
=> "=>"
call_expression
identifier "Err"
arguments
( "("
call_expression
scoped_identifier
identifier "Error"
:: "::"
identifier "InvalidGeneration"
arguments
( "("
call_expression
field_expression
field_expression
identifier "random"
. "."
field_identifier "generations"
. "."
field_identifier "clone"
arguments
( "("
) ")"
) ")"
) ")"
, ","
} "}"
? "?"
; ";"
let_declaration
let "let"
mutable_specifier "mut"
identifier "forms"
= "="
macro_invocation
identifier "vec"
! "!"
token_tree
[ "["
string_literal
" "\""
string_content "regular"
" "\""
. "."
identifier "to_string"
token_tree
( "("
) ")"
] "]"
; ";"
expression_statement
call_expression
field_expression
identifier "forms"
. "."
field_identifier "extend_from_slice"
arguments
( "("
reference_expression
& "&"
field_expression
identifier "pokemon"
. "."
field_identifier "forms"
) ")"
; ";"
line_comment
// "//"
expression_statement
if_expression
if "if"
field_expression
identifier "random"
. "."
field_identifier "no_mega"
block
{ "{"
expression_statement
call_expression
field_expression
identifier "forms"
. "."
field_identifier "retain"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "f"
| "|"
unary_expression
! "!"
call_expression
field_expression
array_expression
[ "["
string_literal
" "\""
string_content "mega"
" "\""
, ","
string_literal
" "\""
string_content "mega-x"
" "\""
, ","
string_literal
" "\""
string_content "mega-y"
" "\""
] "]"
. "."
field_identifier "contains"
arguments
( "("
reference_expression
& "&"
call_expression
field_expression
identifier "f"
. "."
field_identifier "as_str"
arguments
( "("
) ")"
) ")"
) ")"
; ";"
} "}"
expression_statement
if_expression
if "if"
field_expression
identifier "random"
. "."
field_identifier "no_gmax"
block
{ "{"
expression_statement
call_expression
field_expression
identifier "forms"
. "."
field_identifier "retain"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "f"
| "|"
binary_expression
call_expression
field_expression
identifier "f"
. "."
field_identifier "as_str"
arguments
( "("
) ")"
!= "!="
string_literal
" "\""
string_content "gmax"
" "\""
) ")"
; ";"
} "}"
expression_statement
if_expression
if "if"
field_expression
identifier "random"
. "."
field_identifier "no_regional"
block
{ "{"
expression_statement
call_expression
field_expression
identifier "forms"
. "."
field_identifier "retain"
arguments
( "("
closure_expression
closure_parameters
| "|"
identifier "f"
| "|"
unary_expression
! "!"
call_expression
field_expression
array_expression
[ "["
string_literal
" "\""
string_content "alola"
" "\""
, ","
string_literal
" "\""
string_content "galar"
" "\""
, ","
string_literal
" "\""
string_content "hisui"
" "\""
, ","
string_literal
" "\""
string_content "paldea"
" "\""
] "]"
. "."
field_identifier "contains"
arguments
( "("
reference_expression
& "&"
call_expression
field_expression
identifier "f"
. "."
field_identifier "as_str"
arguments
( "("
) ")"
) ")"
) ")"
; ";"
} "}"
line_comment
// "//"
let_declaration
let "let"
identifier "form"
= "="
call_expression
field_expression
call_expression
field_expression
identifier "forms"
. "."
field_identifier "choose"
arguments
( "("
reference_expression
& "&"
mutable_specifier "mut"
call_expression
scoped_identifier
identifier "rand"
:: "::"
identifier "thread_rng"
arguments
( "("
) ")"
) ")"
. "."
field_identifier "unwrap"
arguments
( "("
) ")"
; ";"
let_declaration
let "let"
identifier "shiny"
= "="
binary_expression
call_expression
field_expression
call_expression
scoped_identifier
identifier "rand"
:: "::"
identifier "thread_rng"
arguments
( "("
) ")"
. "."
field_identifier "gen_bool"
arguments
( "("
field_expression
identifier "config"
. "."
field_identifier "shiny_rate"
) ")"
|| "||"
field_expression
identifier "random"
. "."
field_identifier "shiny"
; ";"
call_expression
identifier "show_pokemon_by_name"
arguments
( "("
reference_expression
& "&"
struct_expression
type_identifier "Name"
field_initializer_list
{ "{"
field_initializer
field_identifier "name"
: ":"
call_expression
field_expression
field_expression
identifier "pokemon"
. "."
field_identifier "slug"
. "."
field_identifier "clone"
arguments
( "("
) ")"
, ","
field_initializer
field_identifier "form"
: ":"
call_expression
field_expression
identifier "form"
. "."
field_identifier "to_string"
arguments
( "("
) ")"
, ","
shorthand_field_initializer
identifier "shiny"
, ","
field_initializer
field_identifier "info"
: ":"
field_expression
identifier "random"
. "."
field_identifier "info"
, ","
field_initializer
field_identifier "no_title"
: ":"
field_expression
identifier "random"
. "."
field_identifier "no_title"
, ","
field_initializer
field_identifier "padding_left"
: ":"
field_expression
identifier "random"
. "."
field_identifier "padding_left"
, ","
} "}"
, ","
identifier "pokemon_db"
, ","
identifier "config"
, ","
) ")"
} "}"
function_item
fn "fn"
identifier "main"
parameters
( "("
) ")"
-> "->"
generic_type
type_identifier "Result"
type_arguments
< "<"
unit_type
( "("
) ")"
, ","
type_identifier "Error"
> ">"
block
{ "{"
let_declaration
let "let"
identifier "config"
= "="
try_expression
call_expression
scoped_identifier
identifier "Config"
:: "::"
identifier "load"
arguments
( "("
) ")"
? "?"
; ";"
let_declaration
let "let"
identifier "pokemon_db"
= "="
call_expression
field_expression
call_expression
scoped_identifier
identifier "Asset"
:: "::"
identifier "get"
arguments
( "("
string_literal
" "\""
string_content "pokemon.json"
" "\""
) ")"
. "."
field_identifier "expect"
arguments
( "("
string_literal
" "\""
string_content "Could not read pokemond db file"
" "\""
) ")"
; ";"
let_declaration
let "let"
identifier "pokemon"
= "="
try_expression
call_expression
identifier "load_pokemon"
arguments
( "("
reference_expression
& "&"
identifier "pokemon_db"
) ")"
? "?"
; ";"
let_declaration
let "let"
identifier "args"
= "="
call_expression
scoped_identifier
identifier "Cli"
:: "::"
identifier "parse"
arguments
( "("
) ")"
; ";"
expression_statement
match_expression
match "match"
field_expression
identifier "args"
. "."
field_identifier "command"
match_block
{ "{"
match_arm
match_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "List"
=> "=>"
call_expression
identifier "list_pokemon_names"
arguments
( "("
identifier "pokemon"
) ")"
, ","
match_arm
match_pattern
tuple_struct_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "Name"
( "("
identifier "name"
) ")"
=> "=>"
try_expression
call_expression
identifier "show_pokemon_by_name"
arguments
( "("
reference_expression
& "&"
identifier "name"
, ","
identifier "pokemon"
, ","
reference_expression
& "&"
identifier "config"
) ")"
? "?"
, ","
match_arm
match_pattern
tuple_struct_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "Random"
( "("
identifier "random"
) ")"
=> "=>"
try_expression
call_expression
identifier "show_random_pokemon"
arguments
( "("
reference_expression
& "&"
identifier "random"
, ","
identifier "pokemon"
, ","
reference_expression
& "&"
identifier "config"
) ")"
? "?"
, ","
} "}"
call_expression
identifier "Ok"
arguments
( "("
unit_expression
( "("
) ")"
) ")"
} "}"

After

source_file
mod_item
mod "mod"
identifier "config"
; ";"
mod_item
mod "mod"
identifier "error"
; ";"
mod_item
mod "mod"
identifier "pokemon"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "config"
:: "::"
identifier "Config"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "error"
:: "::"
identifier "Error"
; ";"
use_declaration
use "use"
use_wildcard
identifier "pokemon"
:: "::"
* "*"
; ";"
use_declaration
use "use"
scoped_use_list
identifier "clap"
:: "::"
use_list
{ "{"
identifier "Args"
, ","
identifier "Parser"
, ","
identifier "Subcommand"
} "}"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "rust_embed"
:: "::"
identifier "RustEmbed"
; ";"
use_declaration
use "use"
scoped_identifier
identifier "std"
:: "::"
identifier "str"
; ";"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Print pokemon sprites in your terminal\n"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Parser"
, ","
identifier "Debug"
) ")"
] "]"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "author"
, ","
identifier "version"
, ","
identifier "about"
, ","
identifier "long_about"
= "="
identifier "None"
) ")"
] "]"
struct_item (+21 nodes collapsed)
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Subcommand"
) ")"
] "]"
enum_item
enum "enum"
type_identifier "Commands"
enum_variant_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Print list of all pokemon\n"
enum_variant
identifier "List"
ordered_field_declaration_list
( "("
type_identifier "List"
) ")"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Select pokemon by name. Generally spelled like in the games"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " A few exceptions are nidoran-f, nidoran-m, mr-mime, farfetc"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " flabebe type-null etc. Perhaps grep the output of list if i"...
enum_variant
identifier "Name"
ordered_field_declaration_list
( "("
type_identifier "Name"
) ")"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Show a random pokemon. This command can optionally be follo"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " generation number or range (1-9) to show random pokemon fro"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " generation or range of generations. The generations can be "...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " a continuous range (eg. 1-3) or as a list of generations (1"...
enum_variant
identifier "Random"
ordered_field_declaration_list
( "("
type_identifier "Random"
) ")"
, ","
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "CommonArgs"
field_declaration_list
{ "{"
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Print pokedex entry (if it exists)\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "info" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Show the shiny version of the pokemon instead\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "short" all 2:1
, "," all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "shiny" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Do not display pokemon name\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "no_title" all 2:1
: ":" all 2:1
primitive_type "bool" all 2:1
, "," all 2:1
line_comment all 2:1
// "//" all 2:1
outer_doc_comment_marker all 2:1
/ "/" all 2:1
doc_comment " Left padding\n" all 2:1
attribute_item all 2:1
# "#" all 2:1
[ "[" all 2:1
attribute all 2:1
identifier "clap" all 2:1
token_tree all 2:1
( "(" all 2:1
identifier "long" all 2:1
, "," all 2:1
identifier "default_value" all 2:1
= "=" all 2:1
string_literal all 2:1
" "\"" all 2:1
string_content "0" all 2:1
" "\"" all 2:1
) ")" all 2:1
] "]" all 2:1
field_declaration all 2:1
field_identifier "padding_left" all 2:1
: ":" all 2:1
primitive_type "usize" all 2:1
, "," all 2:1
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "List"
field_declaration_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Generation number, range (1-9), or list of generations (1,3"...
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "default_value"
= "="
string_literal
" "\""
string_content "1-9"
" "\""
) ")"
] "]"
field_declaration
field_identifier "generations"
: ":"
type_identifier "Generations"
, ","
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "Name"
field_declaration_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Name of the pokemon to show\n"
field_declaration
field_identifier "name"
: ":"
type_identifier "String"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Show an alternative form of the pokemon. For example: mega,"...
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " mega-y, gmax, alola, hisui, galar, paldea\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "short"
, ","
identifier "long"
, ","
identifier "default_value"
= "="
string_literal
" "\""
string_content "regular"
" "\""
, ","
identifier "value_parser"
= "="
identifier "Form"
:: "::"
identifier "from_str"
) ")"
] "]"
field_declaration
field_identifier "form"
: ":"
type_identifier "Form"
, ","
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "flatten"
) ")"
] "]"
field_declaration
field_identifier "common"
: ":"
type_identifier "CommonArgs"
, ","
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "Debug"
, ","
identifier "Args"
) ")"
] "]"
struct_item
struct "struct"
type_identifier "Random"
field_declaration_list
{ "{"
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Generation number, range (1-9), or list of generations (1,3"...
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "default_value"
= "="
string_literal
" "\""
string_content "1-9"
" "\""
) ")"
] "]"
field_declaration
field_identifier "generations"
: ":"
type_identifier "Generations"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show mega pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_mega"
: ":"
primitive_type "bool"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show gigantamax pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_gmax"
: ":"
primitive_type "bool"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show regional pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_regional"
: ":"
primitive_type "bool"
, ","
line_comment
// "//"
outer_doc_comment_marker
/ "/"
doc_comment " Do not show any variant-form pokemon\n"
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "long"
) ")"
] "]"
field_declaration
field_identifier "no_variant"
: ":"
primitive_type "bool"
, ","
attribute_item
# "#"
[ "["
attribute
identifier "clap"
token_tree
( "("
identifier "flatten"
) ")"
] "]"
field_declaration
field_identifier "common"
: ":"
type_identifier "CommonArgs"
, ","
} "}"
attribute_item
# "#"
[ "["
attribute
identifier "derive"
token_tree
( "("
identifier "RustEmbed"
) ")"
] "]"
attribute_item
# "#"
[ "["
attribute
identifier "folder"
= "="
string_literal
" "\""
string_content "assets/"
" "\""
] "]"
struct_item
struct "struct"
type_identifier "Asset"
; ";"
function_item
fn "fn"
identifier "main"
parameters
( "("
) ")"
-> "->"
generic_type
type_identifier "Result"
type_arguments
< "<"
unit_type
( "("
) ")"
, ","
type_identifier "Error"
> ">"
block
{ "{"
let_declaration
let "let"
identifier "config"
= "="
try_expression
call_expression
scoped_identifier
identifier "Config"
:: "::"
identifier "load"
arguments
( "("
) ")"
? "?"
; ";"
let_declaration
let "let"
identifier "pokemon_db_file"
= "="
call_expression
field_expression
call_expression
scoped_identifier
identifier "Asset"
:: "::"
identifier "get"
arguments
( "("
string_literal
" "\""
string_content "pokemon.json"
" "\""
) ")"
. "."
field_identifier "expect"
arguments
( "("
string_literal
" "\""
string_content "Could not read pokemon db file"
" "\""
) ")"
; ";"
let_declaration
let "let"
identifier "pokemon_db"
= "="
try_expression
call_expression
scoped_identifier
identifier "PokemonDatabase"
:: "::"
identifier "load"
arguments
( "("
reference_expression
& "&"
identifier "pokemon_db_file"
, ","
identifier "config"
) ")"
? "?"
; ";"
let_declaration
let "let"
identifier "args"
= "="
call_expression
scoped_identifier
identifier "Cli"
:: "::"
identifier "parse"
arguments
( "("
) ")"
; ";"
expression_statement
match_expression
match "match"
field_expression
identifier "args"
. "."
field_identifier "command"
match_block
{ "{"
match_arm
match_pattern
tuple_struct_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "List"
( "("
identifier "list_args"
) ")"
=> "=>"
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "list_pokemon_names"
arguments
( "("
field_expression
identifier "list_args"
. "."
field_identifier "generations"
) ")"
, ","
match_arm
match_pattern
tuple_struct_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "Name"
( "("
identifier "name"
) ")"
=> "=>"
try_expression
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "show_pokemon_by_name"
arguments
( "("
reference_expression
& "&"
identifier "name"
) ")"
? "?"
, ","
match_arm
match_pattern
tuple_struct_pattern
scoped_identifier
identifier "Commands"
:: "::"
identifier "Random"
( "("
identifier "random"
) ")"
=> "=>"
try_expression
call_expression
field_expression
identifier "pokemon_db"
. "."
field_identifier "show_random_pokemon"
arguments
( "("
reference_expression
& "&"
identifier "random"
) ")"
? "?"
, ","
} "}"
call_expression
identifier "Ok"
arguments
( "("
unit_expression
( "("
) ")"
) ")"
} "}"