Skip to content

Commit

Permalink
Merge pull request #7 from w-sodalite/develop
Browse files Browse the repository at this point in the history
支持字段单独校验
  • Loading branch information
w-sodalite authored Oct 11, 2024
2 parents 4c41744 + a3690f9 commit eeb6369
Show file tree
Hide file tree
Showing 10 changed files with 395 additions and 151 deletions.
23 changes: 23 additions & 0 deletions core/src/field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use std::borrow::Cow;

pub trait Field {
///
/// 字段名称
///
fn label(&self) -> &'static str;

///
/// 字段是否必须
///
fn required(&self) -> bool;

///
/// 字段校验
///
fn validate(&self) -> Option<Cow<'static, str>>;

///
/// 设置默认值
///
fn set_default(&self);
}
6 changes: 5 additions & 1 deletion core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
mod field;
mod meta;
mod rw_signal;
mod signal;
#[cfg(feature = "thaw")]
mod thaw;

pub use field::Field;
pub use meta::FieldMeta;
pub use signal::RwSignalField;
pub use rw_signal::RwSignalField;
pub use signal::SignalField;
12 changes: 12 additions & 0 deletions core/src/meta.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
use std::borrow::Cow;

pub trait FieldMeta {
///
/// 字段类型
///
type Type;

///
/// 标签
///
Expand All @@ -8,4 +15,9 @@ pub trait FieldMeta {
/// 是否必须
///
const REQUIRED: bool;

///
/// 校验函数
///
const VALIDATE: fn(&Self::Type) -> Option<Cow<'static, str>>;
}
191 changes: 191 additions & 0 deletions core/src/rw_signal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
use crate::field::Field;
use crate::FieldMeta;
use leptos::*;
use std::borrow::Cow;
use std::marker::PhantomData;

pub struct RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
pub(crate) value: RwSignal<T>,
_mark: PhantomData<M>,
}

impl<M, T> RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
pub fn new(value: T) -> Self {
Self {
value: create_rw_signal(value),
_mark: PhantomData,
}
}
}

impl<M, T> Field for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
fn label(&self) -> &'static str {
M::LABEL
}

fn required(&self) -> bool {
M::REQUIRED
}

fn validate(&self) -> Option<Cow<'static, str>> {
M::VALIDATE(&self.get_untracked())
}

fn set_default(&self) {
self.value.set(Default::default());
}
}

impl<M, T> Default for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
fn default() -> Self {
Self::new(T::default())
}
}

impl<M, T> SignalWithUntracked for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn with_untracked<O>(&self, f: impl FnOnce(&Self::Value) -> O) -> O {
self.value.with_untracked(f)
}

fn try_with_untracked<O>(&self, f: impl FnOnce(&Self::Value) -> O) -> Option<O> {
self.value.try_with_untracked(f)
}
}
impl<M, T> SignalWith for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn with<O>(&self, f: impl FnOnce(&Self::Value) -> O) -> O {
self.value.with(f)
}

fn try_with<O>(&self, f: impl FnOnce(&Self::Value) -> O) -> Option<O> {
self.value.try_with(f)
}
}
impl<M, T> SignalUpdateUntracked<T> for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
fn update_untracked(&self, f: impl FnOnce(&mut T)) {
self.value.update_untracked(f)
}

fn try_update_untracked<O>(&self, f: impl FnOnce(&mut T) -> O) -> Option<O> {
self.value.try_update_untracked(f)
}
}
impl<M, T> SignalUpdate for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn update(&self, f: impl FnOnce(&mut Self::Value)) {
self.value.update(f);
}

fn try_update<O>(&self, f: impl FnOnce(&mut Self::Value) -> O) -> Option<O> {
self.value.try_update(f)
}
}
impl<M, T> SignalSetUntracked<T> for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
fn set_untracked(&self, new_value: T) {
self.value.set_untracked(new_value);
}

fn try_set_untracked(&self, new_value: T) -> Option<T> {
self.value.try_set_untracked(new_value)
}
}
impl<M, T> SignalSet for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn set(&self, new_value: Self::Value) {
self.value.set(new_value);
}

fn try_set(&self, new_value: Self::Value) -> Option<Self::Value> {
self.value.try_set(new_value)
}
}
impl<M, T> SignalGetUntracked for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn get_untracked(&self) -> Self::Value {
self.value.get_untracked()
}

fn try_get_untracked(&self) -> Option<Self::Value> {
self.value.try_get_untracked()
}
}
impl<M, T> SignalGet for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
type Value = T;

fn get(&self) -> Self::Value {
self.value.get()
}

fn try_get(&self) -> Option<Self::Value> {
self.value.try_get()
}
}
impl<M, T> Clone for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
fn clone(&self) -> Self {
*self
}
}
impl<M, T> Copy for RwSignalField<M, T>
where
T: Clone + Default + 'static,
M: FieldMeta<Type = T>,
{
}
Loading

0 comments on commit eeb6369

Please sign in to comment.