mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Make BaseComponent Sealed. (#2359)
This commit is contained in:
parent
e1a9619fba
commit
5dd8b7635c
@ -65,6 +65,8 @@ features = [
|
||||
easybench-wasm = "0.2"
|
||||
wasm-bindgen-test = "0.3"
|
||||
gloo = { version = "0.6", features = ["futures"] }
|
||||
rustversion = "1"
|
||||
trybuild = "1"
|
||||
|
||||
[features]
|
||||
doc_test = []
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
[tasks.native-test]
|
||||
command = "cargo"
|
||||
toolchain = "1.56"
|
||||
args = ["test", "native_"]
|
||||
|
||||
[tasks.test]
|
||||
dependencies = ["native-test"]
|
||||
extend = "core::wasm-pack-base"
|
||||
command = "wasm-pack"
|
||||
args = [
|
||||
|
||||
@ -24,6 +24,9 @@ mod hooks;
|
||||
pub use hooks::*;
|
||||
|
||||
use crate::html::Context;
|
||||
|
||||
use crate::html::SealedBaseComponent;
|
||||
|
||||
/// This attribute creates a function component from a normal Rust function.
|
||||
///
|
||||
/// Functions with this attribute **must** return `Html` and can optionally take an argument for props.
|
||||
@ -100,9 +103,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: 'static> BaseComponent for FunctionComponent<T>
|
||||
impl<T> BaseComponent for FunctionComponent<T>
|
||||
where
|
||||
T: FunctionProvider,
|
||||
T: FunctionProvider + 'static,
|
||||
{
|
||||
type Message = Box<dyn FnOnce() -> bool>;
|
||||
type Properties = T::TProps;
|
||||
@ -167,6 +170,8 @@ pub(crate) fn get_current_scope() -> Option<AnyScope> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SealedBaseComponent for FunctionComponent<T> where T: FunctionProvider + 'static {}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct MsgQueue(Rc<RefCell<Vec<Msg>>>);
|
||||
|
||||
|
||||
@ -34,13 +34,17 @@ impl<COMP: BaseComponent> Context<COMP> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A Sealed trait that prevents direct implementation of
|
||||
/// [BaseComponent].
|
||||
pub trait SealedBaseComponent {}
|
||||
|
||||
/// The common base of both function components and struct components.
|
||||
///
|
||||
/// If you are taken here by doc links, you might be looking for [`Component`] or
|
||||
/// [`#[function_component]`](crate::functional::function_component).
|
||||
///
|
||||
/// We provide a blanket implementation of this trait for every member that implements [`Component`].
|
||||
pub trait BaseComponent: Sized + 'static {
|
||||
pub trait BaseComponent: SealedBaseComponent + Sized + 'static {
|
||||
/// The Component's Message.
|
||||
type Message: 'static;
|
||||
|
||||
@ -160,3 +164,5 @@ where
|
||||
Component::destroy(self, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> SealedBaseComponent for T where T: Sized + Component + 'static {}
|
||||
|
||||
26
packages/yew/tests/failed_tests/base_component_impl-fail.rs
Normal file
26
packages/yew/tests/failed_tests/base_component_impl-fail.rs
Normal file
@ -0,0 +1,26 @@
|
||||
use yew::html::BaseComponent;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct Comp;
|
||||
|
||||
impl BaseComponent for Comp {
|
||||
type Message = ();
|
||||
type Properties = ();
|
||||
|
||||
fn create(_ctx: &Context<Self>) -> Self {
|
||||
Self
|
||||
}
|
||||
fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
|
||||
false
|
||||
}
|
||||
fn changed(&mut self, _ctx: &Context<Self>) -> bool {
|
||||
false
|
||||
}
|
||||
fn view(&self, _ctx: &Context<Self>) -> HtmlResult {
|
||||
todo!()
|
||||
}
|
||||
fn rendered(&mut self, _ctx: &Context<Self>, _first_render: bool) {}
|
||||
fn destroy(&mut self, _ctx: &Context<Self>) {}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@ -0,0 +1,12 @@
|
||||
error[E0277]: the trait bound `Comp: yew::Component` is not satisfied
|
||||
--> tests/failed_tests/base_component_impl-fail.rs:6:6
|
||||
|
|
||||
6 | impl BaseComponent for Comp {
|
||||
| ^^^^^^^^^^^^^ the trait `yew::Component` is not implemented for `Comp`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `SealedBaseComponent` for `Comp`
|
||||
note: required by a bound in `BaseComponent`
|
||||
--> src/html/component/mod.rs
|
||||
|
|
||||
| pub trait BaseComponent: SealedBaseComponent + Sized + 'static {
|
||||
| ^^^^^^^^^^^^^^^^^^^ required by this bound in `BaseComponent`
|
||||
@ -0,0 +1,28 @@
|
||||
use yew::html::BaseComponent;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub struct Comp;
|
||||
|
||||
impl BaseComponent for Comp {
|
||||
type Message = ();
|
||||
type Properties = ();
|
||||
|
||||
fn create(_ctx: &Context<Self>) -> Self {
|
||||
Self
|
||||
}
|
||||
fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> bool {
|
||||
false
|
||||
}
|
||||
fn changed(&mut self, _ctx: &Context<Self>) -> bool {
|
||||
false
|
||||
}
|
||||
fn view(&self, _ctx: &Context<Self>) -> HtmlResult {
|
||||
todo!()
|
||||
}
|
||||
fn rendered(&mut self, _ctx: &Context<Self>, _first_render: bool) {}
|
||||
fn destroy(&mut self, _ctx: &Context<Self>) {}
|
||||
}
|
||||
|
||||
impl yew::html::component::SealedBaseComponent for Comp {}
|
||||
|
||||
fn main() {}
|
||||
@ -0,0 +1,11 @@
|
||||
error[E0603]: module `component` is private
|
||||
--> tests/failed_tests/sealed_base_component_impl-fail.rs:26:17
|
||||
|
|
||||
26 | impl yew::html::component::SealedBaseComponent for Comp {}
|
||||
| ^^^^^^^^^ private module
|
||||
|
|
||||
note: the module `component` is defined here
|
||||
--> src/html/mod.rs
|
||||
|
|
||||
| mod component;
|
||||
| ^^^^^^^^^^^^^^
|
||||
7
packages/yew/tests/native_failed_test.rs
Normal file
7
packages/yew/tests/native_failed_test.rs
Normal file
@ -0,0 +1,7 @@
|
||||
#[allow(dead_code)]
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[rustversion::attr(stable(1.56), test)]
|
||||
fn native_failed_tests() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/failed_tests/*-fail.rs");
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user