wdpe 0.4.2

WebDynpro Parse Engine
Documentation
//! Element registration infrastructure using `inventory`.
//!
//! Each element type submits an [`ElementRegistration`] via `inventory::submit!`
//! (generated by `#[derive(WdElement)]`). At runtime, [`registry_map()`] builds
//! a lazily-initialized `HashMap` from `control_id` to a factory function that
//! creates an [`ElementWrapper`](super::ElementWrapper).

use std::collections::HashMap;
use std::sync::OnceLock;

use super::ElementWrapper;
use crate::error::WebDynproError;

/// Factory function type: given an id string and ElementRef, produces an ElementWrapper.
pub type FactoryFn =
    for<'a> fn(String, scraper::ElementRef<'a>) -> Result<ElementWrapper<'a>, WebDynproError>;

/// A registration entry for a single element type.
pub struct ElementRegistration {
    /// The HTML `ct` attribute value (e.g., "B" for Button)
    pub control_id: &'static str,
    /// Factory function: given an id string and ElementRef, produces an ElementWrapper
    pub from_ref_fn: FactoryFn,
}

impl ElementRegistration {
    /// Creates a new element registration entry.
    pub const fn new(control_id: &'static str, from_ref_fn: FactoryFn) -> Self {
        Self {
            control_id,
            from_ref_fn,
        }
    }
}

inventory::collect!(ElementRegistration);

/// A lazily-initialized map from control_id -> factory function.
pub fn registry_map() -> &'static HashMap<&'static str, FactoryFn> {
    static MAP: OnceLock<HashMap<&'static str, FactoryFn>> = OnceLock::new();
    MAP.get_or_init(|| {
        let mut map = HashMap::with_capacity(32);
        for reg in inventory::iter::<ElementRegistration> {
            map.insert(reg.control_id, reg.from_ref_fn);
        }
        map
    })
}

/// Registration for elements that support text conversion (`textisable`).
pub struct TextisableRegistration {
    /// Function that attempts to convert an ElementWrapper to a String
    pub to_string_fn: for<'a> fn(&ElementWrapper<'a>) -> Option<String>,
}

inventory::collect!(TextisableRegistration);