Understand a function before you read it
What you get
Your agent first sees what a function does, how it is built and who calls it. brief delivers that in one call; read-smart shows the shape of a long function with one line per deep block. The agent then fetches the block it really needs with expand. It does not have to read 200 lines of source for that.
Before and after
The question for serde: What does deserialize_map do in the derive macro, how is it built, and who calls it?
Without greppy
The agent searches for the name, reads the whole function and maps the call site to its function.
$ grep -rnw deserialize_map serde_derive/src
serde_derive/src/de/struct_.rs:97: let visit_map = Stmts(deserialize_map(
serde_derive/src/de/struct_.rs:115: _serde::Deserializer::deserialize_map(__deserializer, self)
serde_derive/src/de/struct_.rs:141: _serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
serde_derive/src/de/struct_.rs:199:fn deserialize_map(
$ sed -n '199,/^}/p' serde_derive/src/de/struct_.rs
fn deserialize_map(
struct_path: &TokenStream,
…
}
$ grep -n '^pub.*fn \|^fn ' serde_derive/src/de/struct_.rs
17:pub(super) fn deserialize(
199:fn deserialize_map(
…
Lines 115 and 141 are tokens in the generated code, not calls. The real call sits in deserialize (line 97).
With greppy
$ greppy brief serde_derive/src/de/struct_.rs::deserialize_map
Generates deserialization code for struct fields.
serde_derive/src/de/struct_.rs:199-205
fn deserialize_map(
…
) -> Fragment {
210 field_i — creates an Ident for a field named after the index
…
317 expr_is_missing — generates code for missing-field validation
…
}
called by deserialize
expand 986e0689aced6bf4 — the call tree below deserialize_map sketched, 7 functions, 59 lines
$ greppy read-smart serde_derive/src/de/struct_.rs::deserialize_map
serde_derive/src/de/struct_.rs:199-419 deserialize_map
…
// Match arms to extract a value for a field.
let value_arms = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
… 240-274 Generates deserialization code for a struct field. — greppy expand c53ffb0c7b71d241
…
brief sketches the flow in 19 lines; read-smart shows the 221 lines as 72 lines of shape. Every folded block carries its expand ID: greppy expand c53ffb0c7b71d241 returns exactly lines 240 to 274, again with folded sub-blocks.
| without greppy | with greppy | |
|---|---|---|
| Calls | 3 | 2 |
| Output characters | 8,419 | 3,699 |
| Tokens | 1,917 | 1,011 |
How it works
brief combines the graph, the source and the local model: it prints the function's purpose in one sentence, its signature verbatim, and then one line per call site or branch with the real symbol and its short description. The callers come from the symbol graph. Structs, enums and traits have no flow, so brief shows their whole definition. read-smart keeps a function's outer levels verbatim and folds every deeper block into one line with line range, description and expand ID; --depth N picks the level. The local model writes the descriptions from the source. Large results wait behind an expand ID, and greppy expand ID prints them in one call.
The commands
| Command | what it does |
|---|---|
greppy brief S |
purpose in one sentence, signature, flow with one line per call or branch, then the callers |
greppy read-smart S |
the definition with folded blocks, one line per block with line range, description and expand ID |
greppy expand ID |
the prepared result of an earlier query, complete in one call |
More in the docs
- Navigate the graph:
briefwith examples - Read source:
read-smartand--depth - Search:
expandand the evidence packs