| Crates.io | guild_core |
| lib.rs | guild_core |
| version | 0.1.0 |
| created_at | 2026-01-05 03:35:36.836714+00 |
| updated_at | 2026-01-05 03:35:36.836714+00 |
| description | Minimal state machine for request-based work coordination. |
| homepage | https://github.com/khatmpeers/GuildCore |
| repository | https://github.com/khatmpeers/GuildCore |
| max_upload_size | |
| id | 2023027 |
| size | 81,260 |
Minimal state machine for request-based work coordination.
Guild-core provides the bare-bones infrastructure for coordinating request-based work:
Guild-core is domain-agnostic, meaning it can work for technical cooperatives, mutual aid networks, research groups, creative collectives, and anything else that features this dynamic.
Add to your Cargo.toml:
[dependencies]
guild-core = "0.1.0"
tokio = { version = "1", features = ["full"] }
Basic example:
use guild_core::{init_board, RequestDraft, Rewardable};
use serde::{Serialize, Deserialize};
use uuid::Uuid;
// Define your reward type with your preferred payment gateway provider
#[derive(Serialize, Deserialize)]
struct Payment {
amount_usd: u64,
}
impl Rewardable for Payment {
fn release_reward(&self) {
println!("Releasing ${}", self.amount_usd);
// Integrate with preferred payment gateway provider API
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Initialize the request board, gives you the SqlitePool object
let pool = init_board("sqlite:board.db").await?;
// Retrieve these from wherever you're storing your client/user data
let client_id: Uuid = ...;
let user_id: Uuid = ...;
// Client creates a request
let draft = RequestDraft::new(
"Build landing page",
"Need a React landing page with responsive design",
None, // labels
Some(vec!["react"]), // tags
client_id
);
// Publish with reward
let request = draft.publish(
Some(Payment { amount_usd: 500 }),
&pool
).await?;
...
// Member claims the request
let accepted = request.claim(member_uuid, &pool).await?;
// Member completes work
accepted.complete(); // Triggers reward.release_reward()
Ok(())
}
Rewardable trait enables generalization; can be fitted to work with any form of compensation so long as the trait is implemented.Guild-core can be used in any request-based application. Some example applications are:
The State Machine is as such.
(RequestStub) -> RequestDraft -(consumes `Rewardable`)-> Request -(consumes `member_id`)-> AcceptedRequest
The entry point to the state machine is the RequestDraft, which exposes a new method. Drafts can be published using the publish method, which will return a Request object and write the request to the board.db file for public viewing. Requests can be delisted, which consumes the object and deletes it from board.db. They can also be claimed using the claim method, which returns an AcceptedRequest which can either be abandoned or completed. Completion will automatically release the trait Rewardable. And by the same token, abandonment will return the request to board.db.
pub trait Rewardable {
fn release_reward(&self);
}
Implement this for your reward type. Examples:
// Monetary reward
struct StripePayment { payment_intent_id: String }
// Academic credit
struct ResearchCredit { course: String, credits: f32 }
// Time bank
struct TimeHours { hours: f32 }
// Portfolio credit (no money)
struct PortfolioCredit { project: String, role: String }
Guild-core's database only stores currently available requests. RequestDrafts and AcceptedRequests will not show up. That is to say, requests are removed from the board once claimed. As such, you should:
Or anything else you'd like persisted.
Guild-core is intentionally minimal.
What is included:
What isn't:
This allows the state machine to remain applicable to various contexts.
Since guild-core specifically handles this core dynamic, you are encouraged to create your own extensions of the dynamic to fully create your ideal "guild."
See The Lake for a reference implementation.
Check the examples/ directory:
basic_usage.rs - Simple request lifecycleEarly Development: Guild-core is in active development. The API may change before 1.0.0.
Current version: 0.1.0 (experimental)
Contributions welcome! Please:
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.