Skip to content

lynnshaoyu/vizcalidraw

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

THIS IS A WORK IN PROGRESS!!! SEVERELY VIBECODED. NOT PRODUCTION READY. DO NOT TAKE ANY OF THIS CODE SERIOUSLY!


vizcalidraw

inverse excalidraw - go from code to graph visualization.

Rust Sparse CLI

Rust Sparse CLI is a small Rust tool that parses a crate’s module imports starting from a given entrypoint, walks through local dependencies in a breadth-first search (BFS) fashion, and produces a module dependency graph in JSON format.

It’s designed for architecture visualization — showing how modules in a codebase are related via uses and contains relationships.


How it Works

Algorithm Overview

  1. Start from the entrypoint
    The user specifies:

    • The crate root folder
    • The main entrypoint file (e.g., compiler.rs)
    • The maximum depth to traverse
  2. Parse imports in the entrypoint

    • Identify all local modules and functions imported in the file
    • Ignore:
      • Utility functions within the same file
      • External crates (std or 3rd-party)
    • Each discovered module is:
      • Added as a node in the graph
      • Added to the BFS processing queue
      • Connected with a uses edge from the current file
  3. Breadth-First Search (BFS)

    • Process files from the queue one at a time
    • For each file:
      • Parse its imports
      • Add any new local modules to the queue
      • Create edges in the graph:
        • uses = current file imports another file
        • contains = module file contains submodules (e.g., mod.rs contains submodule.rs)
  4. Stop conditions

    • Queue is empty
    • Current BFS depth exceeds the user’s max_depth
  5. Output

    • All modules and edges are written to a .json file in this format:
      {
        "nodes": [
          { "id": 0, "kind": "module", "name": "main.rs", "file": "main.rs" }
        ],
        "edges": [
          { "from": 0, "to": 1, "label": "uses" }
        ]
      }

Example

For a simple project:

src/
├── main.rs → imports app, config, io, domain
├── app.rs → imports config, io::fs, io::net, domain::auth, domain::user
├── config.rs
├── io/
│ ├── mod.rs → contains fs, net
│ ├── fs.rs
│ └── net.rs → imports config
└── domain/
├── mod.rs → contains auth, user
├── auth.rs → imports user
└── user.rs

The graph output might look like:

{
  "nodes": [
    { "id": 0, "kind": "module", "name": "main.rs", "file": "main.rs" },
    { "id": 1, "kind": "module", "name": "app.rs", "file": "app.rs" },
    { "id": 2, "kind": "module", "name": "config.rs", "file": "config.rs" },
    { "id": 3, "kind": "module", "name": "io/mod.rs", "file": "io/mod.rs" },
    { "id": 4, "kind": "module", "name": "domain/mod.rs", "file": "domain/mod.rs" },
    { "id": 5, "kind": "module", "name": "io/fs.rs", "file": "io/fs.rs" },
    { "id": 6, "kind": "module", "name": "io/net.rs", "file": "io/net.rs" },
    { "id": 7, "kind": "module", "name": "domain/auth.rs", "file": "domain/auth.rs" },
    { "id": 8, "kind": "module", "name": "domain/user.rs", "file": "domain/user.rs" }
  ],
  "edges": [
    { "from": 0, "to": 1, "label": "contains" },
    { "from": 0, "to": 1, "label": "uses" },
    { "from": 0, "to": 2, "label": "contains" },
    { "from": 0, "to": 3, "label": "contains" },
    { "from": 0, "to": 4, "label": "contains" },
    { "from": 1, "to": 2, "label": "uses" },
    { "from": 1, "to": 5, "label": "uses" },
    { "from": 1, "to": 6, "label": "uses" },
    { "from": 1, "to": 7, "label": "uses" },
    { "from": 1, "to": 8, "label": "uses" },
    { "from": 3, "to": 5, "label": "contains" },
    { "from": 3, "to": 6, "label": "contains" },
    { "from": 4, "to": 7, "label": "contains" },
    { "from": 4, "to": 8, "label": "contains" },
    { "from": 6, "to": 2, "label": "uses" },
    { "from": 7, "to": 8, "label": "uses" }
  ]
}

About

inverse excalidraw - go from code to graph visualization

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors