{"id":47803982,"url":"https://github.com/o3co/rs.hocon","last_synced_at":"2026-05-22T03:13:45.955Z","repository":{"id":348718572,"uuid":"1195786936","full_name":"o3co/rs.hocon","owner":"o3co","description":"Full Lightbend HOCON spec-compliant parser for Rust","archived":false,"fork":false,"pushed_at":"2026-04-03T18:05:27.000Z","size":106,"stargazers_count":1,"open_issues_count":5,"forks_count":0,"subscribers_count":0,"default_branch":"develop","last_synced_at":"2026-04-03T19:11:23.835Z","etag":null,"topics":["config","configuration","hocon","lightbend","parser","rust","serde","typesafe-config"],"latest_commit_sha":null,"homepage":"https://docs.rs/o3co-hocon","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/o3co.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-30T04:05:37.000Z","updated_at":"2026-04-03T18:04:39.000Z","dependencies_parsed_at":null,"dependency_job_id":"fbca1fa3-16b7-40e2-87f0-c04d1e6d260f","html_url":"https://github.com/o3co/rs.hocon","commit_stats":null,"previous_names":["o3co/rs.hocon"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/o3co/rs.hocon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o3co%2Frs.hocon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o3co%2Frs.hocon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o3co%2Frs.hocon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o3co%2Frs.hocon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/o3co","download_url":"https://codeload.github.com/o3co/rs.hocon/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/o3co%2Frs.hocon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31446531,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T15:22:31.103Z","status":"ssl_error","status_checked_at":"2026-04-05T15:22:00.205Z","response_time":75,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["config","configuration","hocon","lightbend","parser","rust","serde","typesafe-config"],"created_at":"2026-04-03T17:23:13.643Z","updated_at":"2026-05-22T03:13:45.949Z","avatar_url":"https://github.com/o3co.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# hocon-parser — Rust 向け HOCON パーサー\n\n[![Crates.io](https://img.shields.io/crates/v/hocon-parser.svg)](https://crates.io/crates/hocon-parser)\n[![docs.rs](https://docs.rs/hocon-parser/badge.svg)](https://docs.rs/hocon-parser)\n[![CI](https://github.com/o3co/rs.hocon/actions/workflows/test.yml/badge.svg)](https://github.com/o3co/rs.hocon/actions/workflows/test.yml)\n[![codecov](https://codecov.io/gh/o3co/rs.hocon/branch/develop/graph/badge.svg)](https://codecov.io/gh/o3co/rs.hocon)\n[![License](https://img.shields.io/crates/l/hocon-parser.svg)](LICENSE)\n\n[Lightbend HOCON 仕様](https://github.com/lightbend/config/blob/main/HOCON.md) の Rust パーサー。手書きレキサー、再帰下降パーサー、型付き `Config` API を備え、オプションで Serde 統合に対応。現在の準拠率は [仕様準拠](#仕様準拠) を参照。\n\n\u003e **[Claude Code](https://claude.ai/claude-code)（Anthropic）による設計・実装。**\n\u003e [GitHub Copilot](https://github.com/features/copilot) および [OpenAI Codex](https://openai.com/index/openai-codex/) によるレビュー。\n\n[English](README.md)\n\n---\n\n## クイックスタート\n\n### 1. インストール\n\n```sh\ncargo add hocon-parser\n```\n\nSerde サポートを有効にする場合:\n\n```sh\ncargo add hocon-parser --features serde\n```\n\n### 2. 使い方\n\n```rust\nuse hocon;\n\nfn main() -\u003e Result\u003c(), Box\u003cdyn std::error::Error\u003e\u003e {\n    let config = hocon::parse(r#\"\n        server {\n            host = \"localhost\"\n            port = 8080\n        }\n        database {\n            url = \"jdbc:postgresql://localhost/mydb\"\n            pool-size = 10\n        }\n    \"#)?;\n\n    let host = config.get_string(\"server.host\")?;\n    let port = config.get_i64(\"server.port\")?;\n\n    println!(\"Server: {}:{}\", host, port);\n    Ok(())\n}\n```\n\n## なぜ HOCON？\n\n| | `.env` | JSON | YAML | HOCON |\n|---|---|---|---|---|\n| Comments | No | No | Yes | Yes |\n| Nesting | No | Yes | Yes | Yes |\n| References / Substitution | No | No | No | Yes (`${var}`) |\n| File inclusion | No | No | No | Yes (`include`) |\n| Object merging | No | No | Anchors (fragile) | Yes (deep merge) |\n| Optional values | No | No | No | Yes (`${?var}`) |\n| Trailing commas | N/A | No | N/A | Yes |\n| Unquoted strings | Yes | No | Yes | Yes |\n\nHOCON は単なるシリアライズ形式ではなく、**プログラムに注入するための設定言語** です。JSON / YAML / TOML はデータ構造の表現に徹しており、ファイルの重ね合わせ・環境変数・参照解決はアプリ側（Pydantic、Serde、Zod 等）の責務になります。HOCON はそれらを仕様そのものに内包しているため、プログラムが設定を受け取る時点で、フォールバックは合成済み・`${VAR}` 参照は解決済みの「1 枚の設定」になっています。「このレイヤーに値があるか？」に由来する条件分岐は、コードではなくフォーマット境界で消えます。\n\n加えて HOCON は YAML の可読性と JSON の構造性を兼ね備えるため、フラットなキーバリュー設定を超えるユースケースには強い選択肢になります。\n\n## 特徴\n\n- 完全な HOCON 構文: オブジェクト、配列、コメント、複数行文字列、クォートなし文字列\n- 変数参照（`${foo}`、`${?foo}`）+ 循環検出\n- `include` ディレクティブ（file、classpath、URL）+ 相対パス解決\n- 仕様準拠のオブジェクトマージ・配列連結\n- 文字列・配列・オブジェクトの値連結\n- Duration・バイトサイズのパース（`10 seconds`、`512 MB`）\n- 環境変数の参照（`${HOME}`）\n- ドット区切りパス式（`server.host`）\n- フォールバック設定のマージ（`with_fallback`）\n- オプションの Serde デシリアライゼーション\n- Lightbend 等価テスト合格（equiv01 - equiv05）\n\n## API リファレンス\n\n### パース\n\n```rust\n// HOCON 文字列をパース\nlet config = hocon::parse(input)?;\n\n// HOCON ファイルをパース（include ディレクティブをファイル位置からの相対パスで解決）\nlet config = hocon::parse_file(\"application.conf\")?;\n\n// カスタム環境変数でパース\nuse std::collections::HashMap;\nlet env: HashMap\u003cString, String\u003e = HashMap::new();\nlet config = hocon::parse_with_env(input, \u0026env)?;\nlet config = hocon::parse_file_with_env(\"application.conf\", \u0026env)?;\n```\n\n### 型付きゲッター\n\nすべての型付きゲッターは `Result\u003cT, ConfigError\u003e` を返します。パスはドット記法を使用。\n\n```rust\nlet host: String    = config.get_string(\"server.host\")?;\nlet port: i64       = config.get_i64(\"server.port\")?;\nlet rate: f64       = config.get_f64(\"rate\")?;\nlet debug: bool     = config.get_bool(\"debug\")?;        // \"yes\"/\"no\"、\"on\"/\"off\" も可\nlet sub: Config     = config.get_config(\"database\")?;    // サブオブジェクトを Config として取得\nlet items: Vec\u003cHoconValue\u003e = config.get_list(\"items\")?;\n```\n\n### Option バリアント\n\n`Result` の代わりに `Option\u003cT\u003e` を返す。キーが存在しないか型が一致しない場合は `None`。\n\n```rust\nlet host: Option\u003cString\u003e = config.get_string_option(\"server.host\");\nlet port: Option\u003ci64\u003e    = config.get_i64_option(\"server.port\");\nlet rate: Option\u003cf64\u003e    = config.get_f64_option(\"rate\");\nlet debug: Option\u003cbool\u003e  = config.get_bool_option(\"debug\");\n```\n\n### Duration・バイトサイズ\n\n```rust\nuse std::time::Duration;\n\n// 対応: ns, us, ms, s/seconds, m/minutes, h/hours, d/days\nlet timeout: Duration = config.get_duration(\"server.timeout\")?;\n\n// 対応: B, KB, KiB, MB, MiB, GB, GiB, TB, TiB（長い形式も可）\nlet max_size: i64 = config.get_bytes(\"upload.max-size\")?;\n```\n\n### 検査\n\n```rust\nlet exists: bool     = config.has(\"server.host\");\nlet keys: Vec\u003c\u0026str\u003e  = config.keys();           // トップレベルキー（挿入順）\nlet raw: Option\u003c\u0026HoconValue\u003e = config.get(\"server.host\");\n```\n\n### フォールバックマージ\n\n```rust\n// レシーバが優先。フォールバックが不足キーを補完。オブジェクトはディープマージ。\nlet merged = app_config.with_fallback(\u0026defaults);\n```\n\n### Serde デシリアライゼーション\n\n`serde` フィーチャーが必要。\n\n```rust\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct ServerConfig {\n    host: String,\n    port: u16,\n}\n\nlet config = hocon::parse(input)?;\nlet server: ServerConfig = config\n    .get_config(\"server\")?\n    .deserialize()?;\n```\n\n## エラー型\n\n| 型 | 発生条件 |\n|------|------|\n| `ParseError` | レキシング/パース時の構文エラー（行・列番号を含む） |\n| `ResolveError` | 変数参照の失敗、循環参照、必須変数の欠落 |\n| `ConfigError` | 値アクセス時のキー欠落・型不一致 |\n| `ConfigError`（未解決の置換プレースホルダーを含むパスへのゲッター呼び出し時は `.is_not_resolved()` で検出、v1.4.0） | 未解決の置換プレースホルダーを含むパスへのゲッター呼び出し |\n| `DeserializeError` | Serde デシリアライゼーション失敗（`serde` フィーチャー使用時） |\n\n## HOCON の例\n\n```hocon\n# コメントは // または #\nserver {\n    host = \"0.0.0.0\"\n    port = 8080\n    timeout = 30 seconds\n    max-upload = 512 MB\n}\n\n# 変数参照\napp {\n    name = \"my-app\"\n    title = \"Welcome to \"${app.name}\n}\n\n# 配列連結\nbase-tags = [\"production\"]\ntags = ${base-tags} [\"v2\"]\n\n# 他のファイルをインクルード\ninclude \"defaults.conf\"\n\n# クォートなし文字列\npath = /usr/local/bin\n\n# 複数行文字列\ndescription = \"\"\"\n    This is a multi-line\n    string value.\n\"\"\"\n\n# オブジェクトマージ\ndefaults { color = \"blue\", size = 10 }\ndefaults { size = 20 }  # マージ: color は保持、size は更新\n```\n\n## 仕様準拠\n\n[Lightbend HOCON 仕様](https://github.com/lightbend/config/blob/main/HOCON.md) への準拠状況は [`docs/spec-compliance.md`](docs/spec-compliance.md) に項目単位で記載しています。以下の表は 2026-05-13 時点のスナップショットです — 最新値は [`xx.hocon/docs/compliance-matrix.md`](https://github.com/o3co/xx.hocon/blob/main/docs/compliance-matrix.md) を参照してください。\n\n| 指標                                  | 状況         |\n| ------------------------------------- | ------------ |\n| 仕様全体（out-of-scope を含む）       | **75.6%**    |\n| In-scope のみ                         | **84.0%**    |\n| Lightbend `equiv01`–`equiv05` テスト  | 5/5 合格     |\n\n## Minimum Supported Rust Version\n\nMSRV は **1.82** です。\n\n## 関連プロジェクト\n\n| プロジェクト | 言語 | レジストリ | 説明 |\n|---------|----------|----------|-------------|\n| [ts.hocon](https://github.com/o3co/ts.hocon) | TypeScript | [npm](https://www.npmjs.com/package/@o3co/ts.hocon) | TypeScript/Node.js 向け HOCON パーサー |\n| [go.hocon](https://github.com/o3co/go.hocon) | Go | [pkg.go.dev](https://pkg.go.dev/github.com/o3co/go.hocon) | Go 向け HOCON パーサー |\n| [hocon2](https://github.com/o3co/hocon2) | Go | [pkg.go.dev](https://pkg.go.dev/github.com/o3co/hocon2) | HOCON → JSON/YAML/TOML/Properties 変換 CLI |\n\n3 つのパーサー実装（[ts.hocon](https://github.com/o3co/ts.hocon)、[rs.hocon](https://github.com/o3co/rs.hocon)、[go.hocon](https://github.com/o3co/go.hocon)）はすべて同じ Lightbend HOCON 仕様で追跡されています — 実装ごとの準拠率は [横断ロールアップ](https://github.com/o3co/xx.hocon/blob/main/docs/compliance-matrix.md) を参照してください。\n\n## ベストプラクティス\n\n### 設定構成\n\n- **ドメインごとに分割**: 設定を論理的な単位に分けましょう（`database.conf`、`server.conf`、`logging.conf`）\n- **`include` で合成**: ドメイン別ファイルからフル設定を組み立てましょう\n- **設定にロジックを入れない**: HOCON は宣言的なデータのためのもので、条件分岐や計算には向きません\n\n### 環境変数\n\n- **`${ENV}` の使用を最小限に**: 設定ファイル自体にデフォルト値を定義し、`${?ENV}`（オプショナル）を使いましょう\n- **ローカル開発で環境変数を必須にしない**: デフォルトだけで動くようにしましょう\n- **必須の環境変数を文書化**: プロジェクトの README や `.env.example` にリストしましょう\n\n### 開発 / 本番の分離\n\n```text\nconfig/\n├── application.conf    # 共有デフォルト\n├── dev.conf            # include \"application.conf\" + 開発用オーバーライド\n└── prod.conf           # include \"application.conf\" + 本番用オーバーライド\n```\n\n### バリデーション\n\n- 設定のバリデーションは常にアプリケーション起動時に行い、使用時ではなく早期に検出しましょう\n- スキーマバリデーション（TypeScript は Zod、Go は struct Unmarshal、Rust は Serde）を使って早期にエラーをキャッチしましょう\n\n```rust\nuse serde::Deserialize;\n\n#[derive(Deserialize)]\nstruct ServerConfig {\n    host: String,\n    port: u16,\n}\n\n#[derive(Deserialize)]\nstruct AppConfig {\n    server: ServerConfig,\n    debug: bool,\n}\n\n// `serde` フィーチャーが必要\nlet cfg: AppConfig = config.deserialize()?; // 起動時に即座に失敗\n```\n\n## 既知の制約\n\n- **`include url(...)`** は未対応です。リモート設定の取得はパーサーのスコープ外です。アプリケーションの HTTP クライアントでコンテンツを取得し、`parse()` に渡してください。\n- **`include classpath(...)`** は未対応です。これは JVM 固有の include 形式で、Java ランタイム外には同等の仕組みがありません。\n- **監視/リロード機能なし** — 設定はロード時に解析されます。ライブリロードには、変更時に `parse()` や `parse_file()` を再度呼び出してください。\n- **ストリーミングパーサーなし** — 入力全体がメモリに読み込まれます。\n- **`.properties` include** — 基本的な `key=value` 形式のみ対応。複数行値（バックスラッシュ継続）、Unicode エスケープ、キーエスケープには対応していません。\n\nAPI の詳細ドキュメントは [docs.rs](https://docs.rs/hocon-parser)（クレート公開後に利用可能）を参照してください。\n\n## セキュリティに関する注意\n\n信頼できない HOCON 入力を解析する場合、以下に注意してください：\n\n- **include のパストラバーサル:** `include \"../../../etc/passwd\"` は `base_dir` からの相対パスで解決されます。信頼できない入力を解析する場合は、include パスを検証してください。\n- **入力サイズ:** パーサーには入力サイズの制限がありません。信頼できない入力の場合は、`parse()` を呼ぶ前にサイズを検証してください。\n\n## ライセンス\n\nApache License 2.0 — [LICENSE](LICENSE) を参照。\n\n## 帰属\n\n[Claude Code](https://claude.ai/claude-code) により設計・実装。\n[GitHub Copilot](https://github.com/features/copilot) および [OpenAI Codex](https://openai.com/index/openai-codex/) によるレビュー。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo3co%2Frs.hocon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo3co%2Frs.hocon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo3co%2Frs.hocon/lists"}