{"id":28760982,"url":"https://github.com/chrisduerr/configory","last_synced_at":"2025-08-17T21:40:28.193Z","repository":{"id":297143636,"uuid":"995805913","full_name":"chrisduerr/configory","owner":"chrisduerr","description":"Batteries included application config management","archived":false,"fork":false,"pushed_at":"2025-07-08T22:19:25.000Z","size":118,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-07-08T22:39:54.111Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chrisduerr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-04T03:17:41.000Z","updated_at":"2025-06-14T02:39:26.000Z","dependencies_parsed_at":"2025-06-04T09:22:46.023Z","dependency_job_id":"9735967e-6275-4271-8b59-2c6fd76b50d4","html_url":"https://github.com/chrisduerr/configory","commit_stats":null,"previous_names":["chrisduerr/configory"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/chrisduerr/configory","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduerr%2Fconfigory","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduerr%2Fconfigory/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduerr%2Fconfigory/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduerr%2Fconfigory/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisduerr","download_url":"https://codeload.github.com/chrisduerr/configory/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisduerr%2Fconfigory/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265542135,"owners_count":23785161,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2025-06-17T06:30:35.828Z","updated_at":"2025-07-16T21:32:25.384Z","avatar_url":"https://github.com/chrisduerr.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Configory\n\nConfigory is a batteries included configuration management library which\nhandles all the gory details of supporting configuration files while also\nsupporting IPC access and overrides.\n\n# Example\n\nTo get a configuration which is backed by a file that is automatically\nreloaded on change, you just need to create a config with `Manager::new`:\n\n```rust\nuse configory::Manager;\n\nlet manager = Manager::new(\"configory\", ()).unwrap();\nmanager.set(\u0026[\"option\"], 3);\n\nassert_eq!(manager.get::\u003c_, i32\u003e(\u0026[\"option\"]), Ok(Some(3)));\n```\n\nThis will also automatically spawn an IPC server which allows configuration\nfile access and modification through a socket file. If you want to disable\nthis, you can use `Manager::with_options`.\n\nThe event handler passed to `Manager::new` or `Manager::with_options`\ncan be used to handle configuration changes, custom IPC messages, and\nerrors.\n\n```rust\nuse std::sync::Arc;\nuse std::sync::atomic::{AtomicU8, Ordering};\n\nuse configory::{Config, EventHandler, Manager};\n\n/// Event handler with a configuration change counter.\nstruct MyEventHandler {\n    changes: Arc\u003cAtomicU8\u003e,\n}\n\nimpl EventHandler\u003c()\u003e for MyEventHandler {\n    fn ipc_changed(\u0026self, _config: \u0026Config) {\n        self.changes.fetch_add(1, Ordering::Relaxed);\n    }\n}\n\n// Register our event handler, which increments a counter on change.\nlet changes = Arc::new(AtomicU8::new(0));\nlet event_handler = MyEventHandler { changes: changes.clone() };\nlet manager = Manager::new(\"configory\", event_handler).unwrap();\n\n// Update the config through direct access and IPC.\nmanager.set(\u0026[\"integer\"], 3);\nmanager.ipc().unwrap().set(\u0026[\"text\"], \"demo\");\n\n// Verify the config is correct and was changed once through IPC.\nassert_eq!(manager.get::\u003c_, String\u003e(\u0026[\"text\"]), Ok(Some(\"demo\".into())));\nassert_eq!(manager.get::\u003c_, i32\u003e(\u0026[\"integer\"]), Ok(Some(3)));\nassert_eq!(changes.load(Ordering::Relaxed), 1);\n```\n\n# IPC client\n\nThe client side of the IPC interface is constructed from the socket path,\nwhich can be acquired using `Manager::ipc` and `Ipc::socket_path`.\n\n```rust\nuse configory::Manager;\nuse configory::ipc::Ipc;\n\n// This would typically happen in a separate process.\nlet manager = Manager::new(\"configory\", ()).unwrap();\nlet socket_path = manager.ipc().unwrap().socket_path();\n\n// Set and retrieve a configuration value through the socket.\nlet ipc = Ipc::client(socket_path);\nipc.set(\u0026[\"option\"], 3).unwrap();\nlet value = ipc.get::\u003c_, i32\u003e(\u0026[\"option\"]).unwrap();\nassert_eq!(value, Some(3));\n```\n\n# Struct Deserialization\n\nIf you prefer accessing configuration values through a struct rather than\nusing the dynamic syntax of `Config::get`, you can deserialize the\ntoplevel value into your struct:\n\n```rust\nuse configory::Manager;\nuse serde::Deserialize;\n\n#[derive(Deserialize, Default, PartialEq, Debug)]\n#[serde(default)]\nstruct MyConfig {\n    field: String,\n}\n\nlet manager = Manager::new(\"configory\", ()).unwrap();\n\n// Without configuration file, the default will be empty.\nlet my_config = manager.get::\u003c\u0026str, MyConfig\u003e(\u0026[]);\nassert_eq!(my_config, Ok(None));\n\n// Once changed wit the path syntax, the field will be uptaded.\nmanager.set(\u0026[\"field\"], \"demo\");\nlet my_config = manager.get::\u003c\u0026str, MyConfig\u003e(\u0026[]).unwrap().unwrap();\nassert_eq!(my_config.field, String::from(\"demo\"));\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisduerr%2Fconfigory","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisduerr%2Fconfigory","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisduerr%2Fconfigory/lists"}