Rust (server)
Transport-agnostic core with an optional blocking ureq transport. #![forbid(unsafe_code)].
| Package | theaimart-adx |
|---|---|
| Language | Rust |
| Distribution | crates.io |
| Requirements | Any recent stable Rust toolchain. |
Install
Cargo.toml
toml
[dependencies]
theaimart-adx = "1.0"Usage
Basic usage
rust
use theaimart_adx::{Adx, AdRequest, render_html};
let adx = Adx::new("pk_your_publisher_key");
let ad = adx.request_ad(&AdRequest {
slot_id: Some("8b1f2c3d-....-uuid"),
page_url: Some("https://yoursite.com/some/page"),
..Default::default()
});
if ad.filled {
let html = render_html(&ad, "theaimart-adx"); // inject into your page
if ad.is_trackable() {
adx.report_viewable(ad.imp_id.as_deref().unwrap_or(""));
}
let _ = html;
}Bring your own transport
rust
use std::time::Duration;
use theaimart_adx::Adx;
use theaimart_adx::transport::{HttpResponse, HttpTransport, TransportError};
struct MyTransport; // wrap reqwest, hyper, etc.
impl HttpTransport for MyTransport {
fn get(&self, url: &str, headers: &[(&str, &str)], timeout: Duration)
-> Result<HttpResponse, TransportError> { todo!() }
fn post(&self, url: &str, headers: &[(&str, &str)], body: &[u8], timeout: Duration)
-> Result<HttpResponse, TransportError> { todo!() }
}
// Works even with default-features = false (no ureq):
let adx = Adx::with_transport("pk_your_publisher_key", MyTransport);Production hardening
- Transport-agnostic core (encoding, parsing, request building) has zero dependencies. The default blocking UreqTransport is behind the ureq feature (on by default); disable it with default-features = false and implement HttpTransport for reqwest/a mock/etc.
- SQL-filter-safe encoding of free-text params so real URLs never trip the backend WAF.
- Fraud-safe User-Agent theaimart-adx-rust/<ver> — off the backend bot blocklist.
- Fail-closed: request_ad never panics or returns Err — a missing slot, transport error, or non-200 yields an un-filled Ad.
- render_html escapes attributes and only turns http/https click URLs into links (a hostile creative's javascript:/file:/intent: URL is dropped). #![forbid(unsafe_code)].
These behaviors come directly from the wire contract — see User-Agent rules and WAF-safe encoding for why they matter. Not getting fills? See Troubleshooting.
API
| Member | Notes |
|---|---|
Adx::new(api_key) | Construct a client with the default ureq transport. |
Adx::with_transport(api_key, transport) | Construct with a custom HttpTransport impl (works with default-features = false). |
adx.request_ad(&AdRequest { .. }) -> Ad | Request an ad decision — never panics. |
adx.report_viewable(imp_id) | Fire the viewability beacon. |
render_html(&ad, css_class) | Render an ad to an escaped HTML snippet. |
The normalized Ad model
Ad mirrors the other server SDKs: filled, kind, source, imp_id, identity_id, creative, auction, reason, plus an is_trackable() helper.
Build & test
bash
cd packages/rust
cargo test # with the default ureq transport (incl. an end-to-end WAF test)
cargo test --no-default-features # the zero-dependency, transport-agnostic core