popper_rs/modifier/
mod.rs1mod offset;
4mod prevent_overflow;
5mod same_width;
6
7pub use offset::*;
8pub use prevent_overflow::*;
9pub use same_width::*;
10
11use crate::sys::ModifierArguments;
12use gloo_utils::format::JsValueSerdeExt;
13use serde_json::json;
14use std::borrow::Cow;
15use std::rc::Rc;
16use wasm_bindgen::closure::Closure;
17use wasm_bindgen::JsValue;
18
19#[derive(Clone, Debug)]
26pub struct ModifierFn(#[allow(clippy::type_complexity)] pub Rc<Closure<dyn Fn(ModifierArguments)>>);
27
28impl PartialEq for ModifierFn {
29 fn eq(&self, other: &Self) -> bool {
30 Rc::ptr_eq(&self.0, &other.0)
31 }
32}
33
34#[derive(Clone, Debug)]
41pub struct EffectFn(#[allow(clippy::type_complexity)] pub Rc<Closure<dyn Fn(ModifierArguments)>>);
42
43impl PartialEq for EffectFn {
44 fn eq(&self, other: &Self) -> bool {
45 Rc::ptr_eq(&self.0, &other.0)
46 }
47}
48
49#[derive(Clone, Debug, PartialEq)]
51pub enum Modifier {
52 Offset(Offset),
53 PreventOverflow(PreventOverflow),
54 SameWidth(SameWidth),
55 Custom {
56 name: Cow<'static, str>,
57 phase: Option<Cow<'static, str>>,
58 enabled: Option<bool>,
59 r#fn: Option<ModifierFn>,
60 },
61}
62
63impl Modifier {
64 pub fn to_value(&self) -> Result<JsValue, JsValue> {
65 match self {
66 Self::Custom {
67 name,
68 phase,
69 enabled,
70 r#fn,
71 } => {
72 let m1 = js_sys::Object::new();
73 js_sys::Reflect::set(&m1, &"name".into(), &JsValue::from_str(name))?;
74 if let Some(phase) = phase {
75 js_sys::Reflect::set(&m1, &"phase".into(), &JsValue::from_str(phase))?;
76 }
77 if let Some(enabled) = enabled {
78 js_sys::Reflect::set(&m1, &"enabled".into(), &JsValue::from_bool(*enabled))?;
79 }
80 if let Some(r#fn) = r#fn {
81 js_sys::Reflect::set(&m1, &"fn".into(), (*r#fn.0).as_ref())?;
82 }
83
84 Ok(m1.into())
85 }
86 Self::Offset(options) => JsValue::from_serde(&json!({
87 "name": "offset",
88 "options": options.to_json(),
89 }))
90 .map_err(|err| JsValue::from_str(&err.to_string())),
91 Self::PreventOverflow(options) => JsValue::from_serde(&json!({
92 "name": "preventOverflow",
93 "options": options.to_json(),
94 }))
95 .map_err(|err| JsValue::from_str(&err.to_string())),
96
97 Self::SameWidth(options) => Ok(options.to_js_value()),
98 }
99 }
100}