use std::any::Any;
pub use annotate;
use annotate::{Function, Module};
pub use phlow_derive::{RawView, environment, extensions, view};
pub use crate::method::*;
pub use crate::object::*;
pub use crate::views::*;
pub use ctor;
pub mod cloning;
mod method;
mod object;
pub mod printing;
mod views;
#[macro_export]
macro_rules! export_link_macro {
($crate_name:ident) => {
#[macro_export]
macro_rules! __phlow_generated_link_macro {
() => {
const _: () = {
#[used]
static __PHLOW_GENERATED_LINK: fn() = ::$crate_name::__ensure_linked;
};
};
}
pub use __phlow_generated_link_macro as link;
};
}
pub fn extension_modules_of_val<T: 'static>(_value: &T) -> Vec<Module> {
extension_modules_of_type::<T>()
}
pub fn extension_modules_of_type<T: 'static>() -> Vec<Module> {
annotate::global_environment().find_modules_such_that(&|module| {
module.has_attribute_such_that(|attribute| {
attribute.name() == "tag" && attribute.is_str("phlow-extensions")
}) && module.has_attribute_such_that(|attribute| {
attribute.name() == "phlow_type" && attribute.is_type::<T>()
})
})
}
pub fn extension_modules_of_any(value: &dyn Any) -> Vec<Module> {
let type_id = value.type_id();
annotate::global_environment().find_modules_such_that(&|module| {
module.has_attribute_such_that(|attribute| {
attribute.name() == "tag" && attribute.is_str("phlow-extensions")
}) && module.has_attribute_such_that(|attribute| {
attribute.name() == "phlow_type" && attribute.is_type_id(&type_id)
})
})
}
pub fn view_functions_of_val<T: 'static>(value: &T) -> Vec<DefiningMethod> {
view_functions_in_modules(&extension_modules_of_val(value))
}
pub fn view_defining_methods_for_type<T: 'static>() -> Vec<DefiningMethod> {
view_functions_in_modules(&extension_modules_of_type::<T>())
}
pub fn view_functions_of_any(value: &dyn Any) -> Vec<DefiningMethod> {
view_functions_in_modules(&extension_modules_of_any(value))
}
pub fn vtable_of_type<T: 'static>() -> PhlowVTable {
vtable_in_modules(&extension_modules_of_type::<T>())
}
pub fn vtable_of_val<T: 'static>(_value: &T) -> PhlowVTable {
vtable_in_modules(&extension_modules_of_type::<T>())
}
pub fn vtable_of_any(value: &dyn Any) -> PhlowVTable {
vtable_in_modules(&extension_modules_of_any(value))
}
fn vtable_in_modules(modules: &[Module]) -> PhlowVTable {
let to_string_fn = functions_in_utility_modules_tagged(modules, "phlow-printing").pop();
let type_name_fn = functions_in_utility_modules_tagged(modules, "phlow-type-name").pop();
let as_view_fn = functions_in_utility_modules_tagged(modules, "phlow-as-view").pop();
let defining_methods_fn =
functions_in_utility_modules_tagged(modules, "phlow-defining-methods").pop();
PhlowVTable {
type_name_fn,
to_string_fn,
as_view_fn,
defining_methods_fn,
}
}
fn view_functions_in_modules(modules: &[Module]) -> Vec<DefiningMethod> {
modules
.iter()
.flat_map(|module| {
module.find_functions_such_that(|function| {
function.has_attribute_such_that(|attribute| {
attribute.name() == "tag" && attribute.is_str("phlow-view")
})
})
})
.map(|each| each.into())
.collect()
}
fn functions_in_utility_modules_tagged(modules: &[Module], tag: &str) -> Vec<Function> {
modules
.iter()
.flat_map(|module| {
module.find_functions_such_that(|function| {
function.has_attribute_such_that(|attribute| {
attribute.name() == "tag" && attribute.is_str(tag)
})
})
})
.collect()
}