{"id":51320919,"url":"https://github.com/madmax983/force-rs","last_synced_at":"2026-07-01T13:30:43.325Z","repository":{"id":337618504,"uuid":"1154023021","full_name":"madmax983/force-rs","owner":"madmax983","description":"Canonical Salesforce Platform API client for Rust","archived":false,"fork":false,"pushed_at":"2026-07-01T11:21:18.000Z","size":9623,"stargazers_count":1,"open_issues_count":289,"forks_count":0,"subscribers_count":0,"default_branch":"trunk-dev","last_synced_at":"2026-07-01T13:14:09.442Z","etag":null,"topics":["api-client","bulk-api","oauth2","rest-api","rust","salesforce"],"latest_commit_sha":null,"homepage":null,"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/madmax983.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":"docs/governance/README.md","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-02-09T23:43:20.000Z","updated_at":"2026-05-19T19:56:21.000Z","dependencies_parsed_at":null,"dependency_job_id":"811beffc-63b0-43ed-b36c-50358e752d62","html_url":"https://github.com/madmax983/force-rs","commit_stats":null,"previous_names":["madmax983/force-rs"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/madmax983/force-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmax983%2Fforce-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmax983%2Fforce-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmax983%2Fforce-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmax983%2Fforce-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/madmax983","download_url":"https://codeload.github.com/madmax983/force-rs/tar.gz/refs/heads/trunk-dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/madmax983%2Fforce-rs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35009266,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-01T02:00:05.325Z","response_time":130,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["api-client","bulk-api","oauth2","rest-api","rust","salesforce"],"created_at":"2026-07-01T13:30:41.384Z","updated_at":"2026-07-01T13:30:43.313Z","avatar_url":"https://github.com/madmax983.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# force-rs\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/madmax983/force-rs/ci.yml?branch=trunk-dev)](https://github.com/madmax983/force-rs/actions)\n[![Crates.io](https://img.shields.io/crates/v/force.svg)](https://crates.io/crates/force)\n[![Documentation](https://docs.rs/force/badge.svg)](https://docs.rs/force)\n[![License](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](LICENSE-MIT)\n\n**A canonical Salesforce Platform API client for Rust** — built with production-grade safety, performance, and developer ergonomics.\n\nforce-rs provides idiomatic Rust bindings to the Salesforce Platform APIs, enabling you to build high-performance integrations, data pipelines, and automation tools. With comprehensive coverage of 7 API surfaces, compile-time safe workflows, and memory-efficient streaming, force-rs is designed for real-world enterprise workloads.\n\nThe workspace also includes [`force-sync`](crates/force-sync), a Postgres-first bidirectional sync engine built on top of `force` and `force-pubsub`.\n\n## Features\n\n### REST API\n- **CRUD Operations** - Create, read, update, delete, and upsert records with full type safety\n- **SOQL Queries** - Execute typed queries with automatic pagination and streaming results\n- **SOSL Search** - Full-text search across multiple objects with builder pattern\n- **Metadata Access** - Describe objects, fields, and org limits programmatically\n- **Relationship Support** - Query parent-child and lookup relationships seamlessly\n\n### Bulk API 2.0\n- **Compile-Time Safety** - Strict guarantees for job lifecycle (Open -\u003e Upload -\u003e InProgress -\u003e Complete)\n- **Ingest Jobs** - Insert, update, upsert, and delete millions of records efficiently\n- **Query Jobs** - Execute bulk queries with streaming CSV results\n- **Memory Efficient** - Stream large datasets without loading entire payloads into RAM\n- **Error Handling** - Comprehensive job monitoring and failure analysis\n\n### Composite API\n- **Batch Requests** - Combine up to 25 subrequests in a single HTTP call\n- **Graph Requests** - Up to 500 nodes with dependency ordering (feature: `composite_graph`)\n- **Reduced API Consumption** - Minimize round trips and stay within governor limits\n\n### Tooling API\n- **Apex Management** - Query and manage Apex classes, triggers, and components\n- **Execute Anonymous** - Run Apex code on the fly with full result inspection\n- **Test Execution** - Run Apex tests synchronously or asynchronously\n- **Code Completions** - IDE-style completions for Apex and Visualforce\n\n### UI API\n- **Layout-Aware Records** - Get presentation-ready data with display values and field visibility\n- **Object Metadata** - Retrieve field info, picklist values, and record type mappings\n- **List Views** - Access list view definitions, columns, and paginated records\n- **Lookups \u0026 Favorites** - Type-ahead search and user favorite management\n\n### GraphQL API\n- **Unified Queries** - Request specific fields and nested relationships in a single call\n- **Typed Results** - Deserialize into custom Rust structs or use dynamic `Value`\n- **Variables \u0026 Operations** - Parameterized queries with named operations\n- **Partial Success Handling** - Inspect both data and errors when both are present\n\n### Core Features\n- **Multiple Auth Flows** - JWT bearer, OAuth 2.0 client credentials\n- **Feature-Gated** - Enable only the APIs you need for minimal binary size\n- **Async/Await** - Built on Tokio for high-concurrency workloads\n- **Type-Safe Errors** - Structured error types with context for debugging\n- **Production Ready** - 870+ tests, zero clippy warnings, comprehensive examples\n\n## Installation\n\nAdd force-rs to your `Cargo.toml`:\n\n```toml\n[dependencies]\nforce = \"0.1\"\ntokio = { version = \"1\", features = [\"full\"] }\nserde = { version = \"1\", features = [\"derive\"] }\nanyhow = \"1.0\"\n\n# Or enable specific features:\nforce = { version = \"0.1\", features = [\"rest\", \"bulk\", \"jwt\"] }\n```\n\n## Quick Start\n\nHere's a minimal example using OAuth 2.0 client credentials to query Salesforce:\n\n```rust\nuse force::auth::ClientCredentials;\nuse force::client::ForceClientBuilder;\nuse serde::Deserialize;\n\n#[derive(Debug, Deserialize)]\nstruct Account {\n    #[serde(rename = \"Id\")]\n    id: String,\n    #[serde(rename = \"Name\")]\n    name: String,\n    #[serde(rename = \"Industry\")]\n    industry: Option\u003cString\u003e,\n}\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    // Authenticate with OAuth 2.0 client credentials\n    let auth = ClientCredentials::new_my_domain(\n        \"your-client-id\",\n        \"your-client-secret\",\n        \"https://your-org.my.salesforce.com\",\n    );\n\n    let client = ForceClientBuilder::new()\n        .authenticate(auth)\n        .build()\n        .await?;\n\n    // Execute typed SOQL query\n    let soql = \"SELECT Id, Name, Industry FROM Account WHERE Industry = 'Technology' LIMIT 10\";\n    let result = client.rest().query::\u003cAccount\u003e(soql).await?;\n\n    // Process results\n    for account in result.records {\n        println!(\"{}: {} ({})\",\n            account.id,\n            account.name,\n            account.industry.unwrap_or_default()\n        );\n    }\n\n    Ok(())\n}\n```\n\n\u003e **Note:** If Salesforce returns a domain-support error for client-credentials auth, use your org's My Domain host, for example `https://your-org.my.salesforce.com`.\n\n## Advanced Examples\n\n### GraphQL Query\n\nQuery specific fields and nested relationships in a single request:\n\n```rust\n// Requires the \"graphql\" feature: force = { version = \"0.1\", features = [\"graphql\"] }\nuse force::api::graphql::GraphqlRequest;\nuse force::auth::ClientCredentials;\nuse force::client::ForceClientBuilder;\nuse serde_json::json;\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let auth = ClientCredentials::new_my_domain(\n        \"client-id\",\n        \"client-secret\",\n        \"https://your-org.my.salesforce.com\",\n    );\n    let client = ForceClientBuilder::new().authenticate(auth).build().await?;\n    let gql = client.graphql();\n\n    // Simple raw query\n    let data = gql.query_raw(\n        r#\"{ uiapi { query { Account(first: 5) {\n            edges { node { Id Name { value } } }\n            totalCount\n        } } } }\"#,\n        None,\n    ).await?;\n\n    println!(\"Total: {}\", data[\"uiapi\"][\"query\"][\"Account\"][\"totalCount\"]);\n\n    // Query with variables\n    let req = GraphqlRequest::new(\"query($limit: Int) { uiapi { query { Account(first: $limit) { edges { node { Id } } } } } }\")\n        .with_variables(json!({\"limit\": 10}))\n        .with_operation_name(\"GetAccounts\");\n    let data: serde_json::Value = gql.query(\u0026req).await?;\n\n    Ok(())\n}\n```\n\n### Bulk Insert with Compile-Time Safety\n\nThe Bulk API uses Rust's type system to enforce the correct job lifecycle at compile time:\n\n```rust\n// Requires the \"bulk\" feature: force = { version = \"0.1\", features = [\"bulk\"] }\nuse force::client::ForceClientBuilder;\nuse force::auth::ClientCredentials;\nuse serde::Serialize;\n\n#[derive(Serialize)]\nstruct Account {\n    #[serde(rename = \"Name\")]\n    name: String,\n    #[serde(rename = \"Industry\")]\n    industry: String,\n}\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let auth = ClientCredentials::new_my_domain(\n        \"client-id\",\n        \"client-secret\",\n        \"https://your-org.my.salesforce.com\",\n    );\n    let client = ForceClientBuilder::new().authenticate(auth).build().await?;\n\n    let accounts = vec![\n        Account { name: \"Acme Corp\".into(), industry: \"Technology\".into() },\n        Account { name: \"Global Ltd\".into(), industry: \"Manufacturing\".into() },\n    ];\n\n    // Convenience method handles: create job -\u003e upload CSV -\u003e close -\u003e poll\n    let job_info = client.bulk().insert(\"Account\", \u0026accounts).await?;\n\n    println!(\"Processed: {}, Failed: {}\",\n        job_info.number_records_processed.unwrap_or(0),\n        job_info.number_records_failed.unwrap_or(0)\n    );\n\n    Ok(())\n}\n```\n\n### Memory-Efficient Bulk Query\n\nStream millions of records without loading the entire dataset into memory:\n\n```rust\n// Requires the \"bulk\" feature: force = { version = \"0.1\", features = [\"bulk\"] }\nuse force::client::ForceClientBuilder;\nuse force::auth::ClientCredentials;\nuse serde::Deserialize;\n// Requires `futures` crate\nuse futures::StreamExt;\n\n#[derive(Debug, Deserialize)]\nstruct Contact {\n    #[serde(rename = \"Id\")]\n    id: String,\n    #[serde(rename = \"Email\")]\n    email: Option\u003cString\u003e,\n}\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let auth = ClientCredentials::new_my_domain(\n        \"client-id\",\n        \"client-secret\",\n        \"https://your-org.my.salesforce.com\",\n    );\n    let client = ForceClientBuilder::new().authenticate(auth).build().await?;\n\n    // Create bulk query job and stream results\n    let stream = client.bulk()\n        .query::\u003cContact\u003e(\n            \"SELECT Id, Email FROM Contact WHERE Email != null\"\n        )\n        .await?;\n    let stream = stream.into_stream();\n    let mut stream = std::pin::pin!(stream);\n\n    let mut count = 0;\n    while let Some(contact_result) = stream.next().await {\n        let contact = contact_result?;\n        println!(\"Processing: {} ({})\", contact.id, contact.email.unwrap_or_default());\n        count += 1;\n    }\n\n    println!(\"Streamed {} contacts\", count);\n    Ok(())\n}\n```\n\n## More Examples\n\nThe [`examples/`](crates/force/examples) directory contains comprehensive demonstrations:\n\n| Example | Feature | Description |\n|---------|---------|-------------|\n| [`basic_crud.rs`](crates/force/examples/basic_crud.rs) | `rest` | Complete CRUD lifecycle (create, read, update, delete) |\n| [`soql_query.rs`](crates/force/examples/soql_query.rs) | `rest` | Typed queries with pagination and relationships |\n| [`dynamic_query.rs`](crates/force/examples/dynamic_query.rs) | `rest` | Dynamic queries without predefined types |\n| [`search.rs`](crates/force/examples/search.rs) | `rest` | SOSL full-text search with builder pattern |\n| [`describe.rs`](crates/force/examples/describe.rs) | `rest` | Object and field metadata introspection |\n| [`org_limits.rs`](crates/force/examples/org_limits.rs) | `rest` | API limits and usage monitoring |\n| [`bulk_insert.rs`](crates/force/examples/bulk_insert.rs) | `bulk` | Bulk insert with job monitoring |\n| [`bulk_query.rs`](crates/force/examples/bulk_query.rs) | `bulk` | Bulk query with streaming results |\n| [`bulk_update.rs`](crates/force/examples/bulk_update.rs) | `bulk` | Bulk update operations |\n| [`bulk_delete.rs`](crates/force/examples/bulk_delete.rs) | `bulk` | Bulk delete with error handling |\n| [`tooling.rs`](crates/force/examples/tooling.rs) | `tooling` | Apex classes, anonymous execution, completions, tests |\n| [`ui_api.rs`](crates/force/examples/ui_api.rs) | `ui` | Layout-aware records, object info, list views, favorites |\n| [`graphql.rs`](crates/force/examples/graphql.rs) | `graphql` | GraphQL queries, typed results, variables, error handling |\n| [`soql_mass_op.rs`](crates/force/examples/soql_mass_op.rs) | `composite` | Composite batch operations |\n| [`query_plan.rs`](crates/force/examples/query_plan.rs) | `rest` | SOQL query plan inspection |\n\nRun any example with:\n\n```bash\ncargo run --example soql_query\ncargo run --example bulk_insert --features bulk\ncargo run --example graphql --features graphql\n```\n\n## Features Reference\n\nforce-rs uses feature flags to minimize dependencies and binary size:\n\n| Feature | Description | Status |\n|---------|-------------|--------|\n| `rest` | REST API (CRUD, SOQL, SOSL, describe, limits) | Default |\n| `bulk` | Bulk API 2.0 (ingest and query jobs) | Stable |\n| `composite` | Composite API (batch requests) | Stable |\n| `composite_graph` | Composite Graph API (dependency-ordered nodes) | Stable |\n| `tooling` | Tooling API (Apex, execute anonymous, tests, completions) | Stable |\n| `ui` | UI API (layout-aware records, object info, list views, favorites) | Stable |\n| `graphql` | GraphQL API (queries, mutations, variables) | Stable |\n| `jwt` | JWT bearer token authentication | Stable |\n| `schema` | Schema analysis, scanning, and code generation utilities | Preview |\n| `data_utility` | Mock-data generation and Salesforce seeding helpers | Preview |\n| `mock` | Wiremock utilities for testing | Stable |\n| `full` | All stable APIs (`rest` + `bulk` + `composite` + `tooling` + `ui` + `graphql` + `jwt`) | Meta |\n| `all` | Everything including preview features | Meta |\n\n**Recommendation:** Start with `default` features, then add `bulk` and `jwt` as needed.\n\n## Preview Features\n\nThe `force` crate includes preview features for early adopters. These capabilities live in their real modules and remain feature-gated while the API settles before a future stabilization pass.\n\n### Query Plan API\n\n\u003e Available with the default `rest` feature.\n\nThe Query Plan API allows you to inspect the performance cost of a SOQL query before executing it. This is useful for identifying inefficient queries (e.g., table scans) in CI/CD pipelines.\n\n```toml\n[dependencies]\nforce = \"0.1\"\n```\n\n```rust\n// Available with the default \"rest\" feature: force = \"0.1\"\nuse force::client::ForceClientBuilder;\nuse force::auth::ClientCredentials;\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    let auth = ClientCredentials::new_my_domain(\n        \"client-id\",\n        \"client-secret\",\n        \"https://your-org.my.salesforce.com\",\n    );\n    let client = ForceClientBuilder::new().authenticate(auth).build().await?;\n\n    let soql = \"SELECT Id FROM Account WHERE Name LIKE 'A%'\";\n    let explanation = client.rest().explain(soql).await?;\n\n    for plan in explanation.plans {\n        println!(\"Plan: {}, Cost: {}\", plan.leading_operation_type, plan.relative_cost);\n        for note in plan.notes {\n            println!(\"  Note: {}\", note.description);\n        }\n    }\n    Ok(())\n}\n```\n\n### Preview Utility Modules\n\nPreview utilities now live in the modules that own them:\n\n- **`force::api::composite::{QueryBatch, SoqlMassOp}`**: batch-aware helpers built on the Composite API.\n- **`force::api::rest::analyze_query_plan`**: turns `explain()` responses into actionable warnings.\n- **`force::schema`**: schema scanning, diffing, visualization, DDL export, and code generation helpers.\n- **`force::data`**: mock-record generation and bulk seeding helpers.\n\n## Architecture\n\nforce-rs is built around a handler pattern where each API surface gets its own feature-gated handler type:\n\n```\nForceClient\u003cA\u003e\n  |-- .rest()       -\u003e RestHandler\u003cA\u003e       (feature: rest)\n  |-- .bulk()       -\u003e BulkHandler\u003cA\u003e       (feature: bulk)\n  |-- .composite()  -\u003e CompositeHandler\u003cA\u003e  (feature: composite)\n  |-- .tooling()    -\u003e ToolingHandler\u003cA\u003e    (feature: tooling)\n  |-- .ui()         -\u003e UiHandler\u003cA\u003e         (feature: ui)\n  |-- .graphql()    -\u003e GraphqlHandler\u003cA\u003e    (feature: graphql)\n```\n\nAll handlers share a common `Session\u003cA\u003e` (via `Arc`) containing the HTTP client, token manager, and configuration. This ensures zero-cost handler creation and shared authentication state.\n\nFor the sync layer, see [`crates/force-sync`](crates/force-sync) and its design notes in [`docs/adr/026-force-sync-crate.md`](docs/adr/026-force-sync-crate.md).\n\nArchitectural decisions are documented in [`docs/adr/`](docs/adr/):\n\n| ADR | Decision |\n|-----|----------|\n| [001](docs/adr/001-workspace-structure.md) | Workspace structure and module organization |\n| [002](docs/adr/002-authentication-strategy.md) | Authentication trait design and flow support |\n| [003](docs/adr/003-error-handling.md) | Error hierarchy with thiserror |\n| [004](docs/adr/004-feature-gates.md) | Feature flag strategy for API surfaces |\n| [005](docs/adr/005-compile-time-auth-safety.md) | Compile-time auth safety with phantom types |\n| [006](docs/adr/006-handler-pattern.md) | Handler pattern for API organization |\n| [007](docs/adr/007-rest-api-design.md) | REST API design decisions |\n| [019](docs/adr/019-tooling-api-design.md) | RestOperation trait and Tooling API |\n| [020](docs/adr/020-ui-api-design.md) | UI API handler design |\n| [021](docs/adr/021-graphql-api-design.md) | GraphQL API error handling strategy |\n\n## Testing\n\nforce-rs has comprehensive test coverage (870+ tests) using wiremock for HTTP mocking:\n\n```bash\n# Run all tests\ncargo test --all-features\n\n# Run with logging\nRUST_LOG=debug cargo test --all-features\n\n# Run specific API surface tests\ncargo test --features graphql -- graphql\ncargo test --features bulk -- bulk\n```\n\nNightly live-contract tests (ignored by default in local runs) are available in CI and can be run manually with org credentials. OAuth URL env vars accept a bare host, an org base URL, or the full OAuth token endpoint; bare hosts are treated as HTTPS. Client-credentials live tests require `SF_TOKEN_URL` to be set explicitly for the target org/environment. Pub/Sub live tests require `SF_PUBSUB_TOPIC` to name an accessible event topic, for example `/data/AccountChangeEvent`; `SF_PUBSUB_ENDPOINT` defaults to `https://api.pubsub.salesforce.com:7443`.\n\n## Enterprise DX and Governance\n\n### Runbooks\n\n- [Auth Credential Rotation](docs/runbooks/auth-credential-rotation.md)\n- [Rate-Limit Incident Response](docs/runbooks/rate-limit-incident.md)\n- [Retry and Polling Tuning](docs/runbooks/retry-tuning.md)\n- [Salesforce API Version Upgrade](docs/runbooks/salesforce-api-version-upgrade.md)\n- [Documentation Index](docs/README.md)\n\n### API Guarantees\n\nThe crate-level compatibility and feature-flag guarantees are documented in:\n\n- [API Stability and SemVer Policy](docs/governance/api-stability-policy.md)\n\n### Incubation Specs\n\n- [Vantage Specs Index](docs/vantage/README.md)\n\n### CI Lanes\n\n- Fast unit/lint/format gates for PR velocity\n- Full test lanes for broader confidence\n- Nightly live-contract workflow for real Salesforce contract validation\n\n## Contributing\n\nContributions are welcome! force-rs follows strict TDD discipline and quality standards:\n\n- **Test-Driven Development** - All features require failing tests first (RED -\u003e GREEN -\u003e REFACTOR)\n- **Code Quality** - `cargo fmt` and `cargo clippy -- -D warnings` must pass\n- **Documentation** - All public APIs require doc comments with examples\n- **Architecture** - ADRs (Architecture Decision Records) for significant changes\n\nSee [`CONTRIBUTING.md`](CONTRIBUTING.md) for detailed guidelines.\n\n## License\n\nLicensed under either of:\n\n- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)\n\nat your option.\n\n### Contribution\n\nUnless 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.\n\n---\n\n**Built by the force-rs contributors** | [Documentation](https://docs.rs/force) | [Examples](crates/force/examples) | [Issues](https://github.com/markm/force-rs/issues)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmax983%2Fforce-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmadmax983%2Fforce-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmadmax983%2Fforce-rs/lists"}