use std::num::NonZeroU32;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, Mutex};
use maplibre_native::{
register_file_source_callback, FsResponse, Height, ImageRendererBuilder, ResourceKind, Size,
Width,
};
const INLINE_STYLE: &str = r#"{
"version": 8,
"name": "callback-test",
"sources": {},
"layers": [
{ "id": "bg", "type": "background", "paint": { "background-color": "rgb(255, 128, 0)" } }
]
}"#;
#[test]
fn file_source_callback_serves_inline_style() {
let seen_urls: Arc<Mutex<Vec<String>>> = Arc::new(Mutex::new(Vec::new()));
let call_count = Arc::new(AtomicUsize::new(0));
let seen_urls_cb = seen_urls.clone();
let call_count_cb = call_count.clone();
register_file_source_callback(move |url: &str, kind: ResourceKind| {
call_count_cb.fetch_add(1, Ordering::SeqCst);
seen_urls_cb.lock().unwrap().push(format!("{kind:?}:{url}"));
if url.ends_with("/inline-style.json") {
FsResponse::Ok(INLINE_STYLE.as_bytes().to_vec())
} else {
FsResponse::NoContent
}
});
let mut renderer = ImageRendererBuilder::new()
.with_size(NonZeroU32::new(64).unwrap(), NonZeroU32::new(64).unwrap())
.with_pixel_ratio(1.0)
.build_static_renderer();
let url: url::Url = "https://example.invalid/inline-style.json".parse().unwrap();
renderer.load_style_from_url(&url);
renderer.set_map_size(Size::new(Width(64), Height(64)));
let image = renderer.render_static(0.0, 0.0, 0.0, 0.0, 0.0).expect("render should succeed");
let buf = image.as_image();
assert_eq!(buf.width(), 64);
assert_eq!(buf.height(), 64);
let calls = call_count.load(Ordering::SeqCst);
assert!(calls >= 1, "expected ≥1 callback invocation, got {calls}");
let urls = seen_urls.lock().unwrap();
assert!(!urls.is_empty());
assert!(
urls[0].contains("inline-style.json"),
"first callback url was not the style: {:?}",
urls[0]
);
let mut saw_orange = false;
for p in buf.pixels() {
let [r, g, b, a] = p.0;
if a >= 250
&& (i32::from(r) - 255).abs() <= 2
&& (i32::from(g) - 128).abs() <= 2
&& i32::from(b) <= 2
{
saw_orange = true;
break;
}
}
assert!(saw_orange, "expected to see rgb(255,128,0) pixels in the rendered image");
}