Dots

ブログとWEBアプリ

Rust製ER図DSLコンパイラ


rusterd - Rust製ER図DSLコンパイラ

rusterd logo

claude code に鞭を打って、ER図を描くツールを作ってみた。

rusterdは、ER図(エンティティ関連図)をテキストで記述し、SVGにレンダリングするDSLコンパイラ。

リポジトリ: https://github.com/misebox/rusterd

デモ用ページ: /pages/rusterd-demo/

Rustで実装されており、wasm-packでビルドしたものをnpmパッケージとして公開しているので、ブラウザでも動作する。

インストールと使用方法

CLI

cargo build --release
rusterd input.erd -o output.svg

JavaScriptでの利用(WASM)

bun add rusterd

erdToSvg()関数を使用してERD記法からSVGを生成できます。

import init, { erdToSvg } from 'rusterd';

await init();
const svg = erdToSvg(erdSource);

ただこれ、XSSに怯えながら使うことになりそう。

reactだとdangerouslySetInnerHTMLを使うことになる。

大丈夫だと思うけど、ユーザー入力を直接渡すのは怖いのかもなぁ。

Reactコンポーネント例


import React, { useEffect, useState } from 'react';
import init, { erdToSvg } from 'rusterd';

export function ERDiagram({ erdSource }) {
  const [svg, setSvg] = useState('');
  const [ready, setReady] = useState(false);

  useEffect(() => {
    let mounted = true;
    (async () => {
      await init();
      if (mounted) setReady(true);
    })();
    return () => { mounted = false; };
  }, []);

  useEffect(() => {
    if (!ready) return;
    try {
      const out = erdToSvg(erdSource);
      setSvg(out);
    } catch (e) {
      console.error('Failed to render ERD:', e);
      setSvg('<svg xmlns="http://www.w3.org/2000/svg"><text x="10" y="20">Render error</text></svg>');
    }
  }, [ready, erdSource]);

  return (
    <div
      className="erd-svg"
      dangerouslySetInnerHTML=
    />
  );
}

// 使用例
// <ERDiagram erdSource={`
// entity User {
//   id int
//   name string
// }
// @hint.arrangement {
//   User at (0,0)
// }
// `} />

ERD記法

「ERD記法」は、オリジナル記法で、エンティティ、属性、リレーションシップを簡潔??に記述できる。

(自分で書いてみると結構面倒だったので、改良の余地あり。)

基本構文の例:

entity Category {
    id int pk
    parent_id int fk -> Category.id
    name string not null
}

entity Product {
    id int pk
    category_id int fk -> Category.id
    name string not null
}
rel {
    Category 1 -- * Product
}
# Grid-based layout
@hint.arrangement = {
    Category;
    Product
}

# view product only
view product {
    include Product
}

レイアウト制御

ER図を自動生成するとレイアウトが見づらくなりがちなので、表示を調整するために、グリッドベースで配置を制御するarrangement機能を用意している。

@hint.arrangementを使用することで、グリッドベースでエンティティの配置を制御できる。

@hint.arrangement = {
    Category;
    Product
}

ビュー機能

viewブロックを使用して、特定のエンティティや関連だけを抽出した図を生成できる。

これにより、いちいち部分的なER図を別々に書かなくても済む。

# view product only
view product {
    include Product
}

詳細レベル

表示内容を以下のレベルで制御できる。

同じERD記法から異なる詳細レベルの図を生成できる。

テーブル数が増えたときにごちゃごちゃするときは、一旦テーブル名だけで表示してみたりもできる。

CLI

rusterd input.erd -o output.svg --detail pkfk

JavaScript

const svgPkOnly = erdToSvg(erdSource, { detail: 'pk' });
const svgAll = erdToSvg(erdSource, { detail: 'all' });