Parse a Rust source file into a syn_serde::File and print out a Pickle representation of the syntax tree.

text cargo run src/main.rs t.pickle python3 t.py where the python3 script t.py is specified as follows:

```python3

Load the dictionary back from the pickle file.

import pickle import pprint ast = pickle.load(open("t.pickle", "rb")) pp = pprint.PrettyPrinter(indent=4) pp.pprint(ast) ```

The output is listed here:

{ 'attrs': [ { 'path': {'segments': [{'ident': 'warn'}]}, 'style': ('inner',), 'tokens': [ ( 'group', { 'delimiter': ('parenthesis',), 'stream': [ ( 'ident', 'rust_2018_idioms'), ( 'punct', { 'op': ',', 'spacing': ( 'alone',)}), ( 'ident', 'single_use_lifetimes')]})]}], 'items': [ ( 'use', { 'tree': ( 'path', { 'ident': 'std', 'tree': ('ident', 'fs')})}), ( 'use', { 'tree': ( 'path', { 'ident': 'structopt', 'tree': ('ident', 'StructOpt')})}), ('mod', {'ident': 'pickle', 'semi': True}), ( 'struct', { 'attrs': [ { 'path': { 'segments': [ { 'ident': 'doc'}]}, 'style': ('outer',), 'tokens': [ ( 'punct', { 'op': '=', 'spacing': ( 'alone',)}), ( 'lit', '" Search for a ' 'pattern in a file ' 'and display the ' 'lines that ' 'contain it."')]}, { 'path': { 'segments': [ { 'ident': 'derive'}]}, 'style': ('outer',), 'tokens': [ ( 'group', { 'delimiter': ( 'parenthesis',), 'stream': [ ( 'ident', 'StructOpt')]})]}], 'fields': ( 'named', [ { 'attrs': [ { 'path': { 'segments': [ { 'ident': 'structopt'}]}, 'style': ( 'outer',), 'tokens': [ ( 'group', { 'delimiter': ( 'parenthesis',), 'stream': [ ( 'ident', 'parse'), ( 'group', { 'delimiter': ( 'parenthesis',), 'stream': [ ( 'ident', 'from_os_str')]})]})]}], 'colon_token': True, 'ident': 'input', 'ty': ( 'path', { 'segments': [ { 'ident': 'std'}, { 'ident': 'path'}, { 'ident': 'PathBuf'}]})}, { 'attrs': [ { 'path': { 'segments': [ { 'ident': 'structopt'}]}, 'style': ( 'outer',), 'tokens': [ ( 'group', { 'delimiter': ( 'parenthesis',), 'stream': [ ( 'ident', 'parse'), ( 'group', { 'delimiter': ( 'parenthesis',), 'stream': [ ( 'ident', 'from_os_str')]})]})]}], 'colon_token': True, 'ident': 'output', 'ty': ( 'path', { 'segments': [ { 'ident': 'std'}, { 'ident': 'path'}, { 'ident': 'PathBuf'}]})}]), 'ident': 'Cli'}), ( 'type', { 'generics': {'params': [('type', {'ident': 'T'})]}, 'ident': 'Result', 'ty': ( 'path', { 'segments': [ {'ident': 'std'}, {'ident': 'result'}, { 'arguments': ( 'angle_bracketed', { 'args': [ ( 'type', ( 'path', { 'segments': [ { 'ident': 'T'}]})), ( 'type', ( 'path', { 'segments': [ { 'arguments': ( 'angle_bracketed', { 'args': [ ( 'type', ( 'trait_object', { 'bounds': [ ( 'trait', { 'path': { 'segments': [ { 'ident': 'std'}, { 'ident': 'error'}, { 'ident': 'Error'}]}})], 'dyn': True}))]}), 'ident': 'Box'}]}))]}), 'ident': 'Result'}]})}), ( 'fn', { 'ident': 'main', 'inputs': [], 'output': None, 'stmts': [ ( 'expr', ( 'if', { 'cond': ( 'let', { 'expr': ( 'call', { 'args': [ ], 'func': ( 'path', { 'segments': [ { 'ident': 'try_main'}]})}), 'pat': ( 'tuple_struct', { 'pat': { 'elems': [ ( 'ident', { 'ident': 'e'})]}, 'path': { 'segments': [ { 'ident': 'Err'}]}})}), 'then_branch': [ ( 'semi', ( 'macro', { 'delimiter': ( 'paren',), 'path': { 'segments': [ { 'ident': 'eprintln'}]}, 'tokens': [ ( 'lit', '"{}"'), ( 'punct', { 'op': ',', 'spacing': ( 'alone',)}), ( 'ident', 'e')]})), ( 'semi', ( 'call', { 'args': [ ( 'lit', { 'int': '1'})], 'func': ( 'path', { 'segments': [ { 'ident': 'std'}, { 'ident': 'process'}, { 'ident': 'exit'}]})}))]}))]}), ( 'fn', { 'ident': 'try_main', 'inputs': [], 'output': ( 'path', { 'segments': [ { 'arguments': ( 'angle_bracketed', { 'args': [ ( 'type', ( 'tuple', { 'elems': [ ]}))]}), 'ident': 'Result'}]}), 'stmts': [ ( 'let', { 'init': ( 'call', { 'args': [], 'func': ( 'path', { 'segments': [ { 'ident': 'Cli'}, { 'ident': 'from_args'}]})}), 'pat': ( 'ident', {'ident': 'args'})}), ( 'let', { 'init': ( 'field', { 'base': ( 'path', { 'segments': [ { 'ident': 'args'}]}), 'ident': 'input'}), 'pat': ( 'ident', { 'ident': 'filepath'})}), ( 'let', { 'init': ( 'try', { 'expr': ( 'call', { 'args': [ ( 'reference', { 'expr': ( 'path', { 'segments': [ { 'ident': 'filepath'}]})})], 'func': ( 'path', { 'segments': [ { 'ident': 'fs'}, { 'ident': 'read_to_string'}]})})}), 'pat': ( 'ident', {'ident': 'code'})}), ( 'let', { 'init': ( 'try', { 'expr': ( 'call', { 'args': [ ( 'reference', { 'expr': ( 'path', { 'segments': [ { 'ident': 'code'}]})})], 'func': ( 'path', { 'segments': [ { 'ident': 'syn'}, { 'ident': 'parse_file'}]})})}), 'pat': ( 'ident', {'ident': 'syntax'})}), ( 'let', { 'init': ( 'call', { 'args': [ ( 'reference', { 'expr': ( 'path', { 'segments': [ { 'ident': 'syntax'}]})})], 'func': ( 'path', { 'segments': [ { 'ident': 'pickle'}, { 'ident': 'to_vec'}]})}), 'pat': ( 'ident', {'ident': 'buf'})}), ( 'let', { 'init': ( 'call', { 'args': [ ( 'field', { 'base': ( 'path', { 'segments': [ { 'ident': 'args'}]}), 'ident': 'output'}), ( 'path', { 'segments': [ { 'ident': 'buf'}]})], 'func': ( 'path', { 'segments': [ { 'ident': 'fs'}, { 'ident': 'write'}]})}), 'pat': ('_', {})}), ( 'expr', ( 'call', { 'args': [ ( 'tuple', { 'elems': [ ]})], 'func': ( 'path', { 'segments': [ { 'ident': 'Ok'}]})}))]})]}

Acknowledgement

This utility is made available thanks to syn-serde.