use ag_grid_derive::FromInterface;
use js_sys::Function;
use serde::Serialize;
use wasm_bindgen::prelude::*;
use crate::RowData;
#[wasm_bindgen]
extern "C" {
pub type IGetRowsParams;
#[wasm_bindgen(method, getter, js_name = startRow)]
pub fn start_row(this: &IGetRowsParams) -> u32;
#[wasm_bindgen(method, getter, js_name = endRow)]
pub fn end_row(this: &IGetRowsParams) -> u32;
#[wasm_bindgen(method, getter, js_name = sortModel)]
pub fn sort_model(this: &IGetRowsParams) -> Vec<ISortModelItem>;
#[wasm_bindgen(method, getter, js_name = filterModel)]
pub fn filter_model(this: &IGetRowsParams) -> JsValue;
#[wasm_bindgen(method, getter, js_name = successCallback)]
pub fn success_callback(this: &IGetRowsParams) -> Function;
#[wasm_bindgen(method, getter, js_name = failCallback)]
pub fn fail_callback(this: &IGetRowsParams) -> Function;
}
#[derive(FromInterface)]
pub struct GetRowsParams {
pub start_row: u32,
pub end_row: u32,
pub sort_model: std::vec::Vec<SortModelItem>,
}
#[wasm_bindgen]
extern "C" {
pub type ISortModelItem;
#[wasm_bindgen(method, getter, js_name = colId)]
pub fn col_id(this: &ISortModelItem) -> String;
#[wasm_bindgen(method, getter)]
pub fn sort(this: &ISortModelItem) -> SortDirection;
}
#[derive(Debug, FromInterface)]
pub struct SortModelItem {
pub col_id: String,
pub sort: SortDirection,
}
#[derive(Debug)]
#[wasm_bindgen]
pub enum SortDirection {
Asc,
Desc,
}
#[wasm_bindgen]
pub struct DataSource {
#[wasm_bindgen(readonly, getter_with_clone, js_name = getRows)]
pub get_rows: JsValue,
}
pub struct DataSourceBuilder {
get_rows: Closure<dyn FnMut(IGetRowsParams)>,
}
impl DataSourceBuilder {
pub fn new<F>(mut get_rows: F) -> Self
where
F: FnMut(GetRowsParams) -> Result<Vec<RowData>, Box<dyn std::error::Error>> + 'static,
{
let get_rows: Closure<dyn FnMut(IGetRowsParams)> =
Closure::new(move |js_params: IGetRowsParams| {
let params = GetRowsParams::from(&js_params);
let row_data = get_rows(params);
match row_data {
Ok(data) => {
let data = serde_wasm_bindgen::to_value(&data)
.expect("failed converting row data to JsValue");
js_params
.success_callback()
.call1(&JsValue::null(), &data)
.expect("failed calling success callback")
}
Err(_) => js_params
.fail_callback()
.call0(&JsValue::null())
.expect("failed calling failure callback"),
};
});
Self { get_rows }
}
pub fn build(self) -> DataSource {
DataSource {
get_rows: self.get_rows.into_js_value(),
}
}
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub enum RowModelType {
Infinite,
Viewport,
ClientSide,
ServerSide,
}
pub enum Filter {
AgNumberColumnFilter,
AgTextColumnFilter,
AgDateColumnFilter,
AgSetColumnFilter,
True,
False,
}
impl Serialize for Filter {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
match *self {
Filter::AgNumberColumnFilter => serializer.serialize_str("agNumberColumnFilter"),
Filter::AgTextColumnFilter => serializer.serialize_str("agTextColumnFilter"),
Filter::AgDateColumnFilter => serializer.serialize_str("agDateColumnFilter"),
Filter::AgSetColumnFilter => serializer.serialize_str("agSetColumnFilter"),
Filter::True => serializer.serialize_bool(true),
Filter::False => serializer.serialize_bool(false),
}
}
}
#[cfg(test)]
mod tests {
use serde_json::{json, to_value};
use super::*;
#[test]
#[rustfmt::skip]
fn test_serialize_filter() {
assert_eq!(to_value(Filter::AgNumberColumnFilter).unwrap(), json!("agNumberColumnFilter"));
assert_eq!(to_value(Filter::AgTextColumnFilter).unwrap(), json!("agTextColumnFilter"));
assert_eq!(to_value(Filter::AgDateColumnFilter).unwrap(), json!("agDateColumnFilter"));
assert_eq!(to_value(Filter::AgSetColumnFilter).unwrap(), json!("agSetColumnFilter"));
assert_eq!(to_value(Filter::True).unwrap(), json!(true));
assert_eq!(to_value(Filter::False).unwrap(), json!(false));
}
#[test]
#[rustfmt::skip]
fn test_serialize_row_model_type() {
assert_eq!(to_value(RowModelType::Infinite).unwrap(), json!("infinite"));
assert_eq!(to_value(RowModelType::Viewport).unwrap(), json!("viewport"));
assert_eq!(to_value(RowModelType::ClientSide).unwrap(), json!("clientSide"));
assert_eq!(to_value(RowModelType::ServerSide).unwrap(), json!("serverSide"));
}
}