Skip to content

Commit

Permalink
Improve the ORM support for SQLite
Browse files Browse the repository at this point in the history
  • Loading branch information
photino committed Jan 3, 2024
1 parent 4fc633a commit 50cb615
Show file tree
Hide file tree
Showing 18 changed files with 259 additions and 21 deletions.
2 changes: 1 addition & 1 deletion examples/actix-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ actix-web = "4.4.0"
tracing = "0.1.40"

[dependencies.serde]
version = "1.0.193"
version = "1.0.194"
features = ["derive"]

[dependencies.zino]
Expand Down
2 changes: 1 addition & 1 deletion examples/axum-app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ axum = "0.6.20"
tracing = "0.1.40"

[dependencies.serde]
version = "1.0.193"
version = "1.0.194"
features = ["derive"]

[dependencies.zino]
Expand Down
2 changes: 1 addition & 1 deletion examples/dioxus-desktop/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ features = [
]

[dependencies.serde]
version = "1.0.193"
version = "1.0.194"
features = ["derive"]

[dependencies.zino]
Expand Down
6 changes: 3 additions & 3 deletions examples/dioxus-desktop/src/view/overview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,21 +70,21 @@ pub fn Overview(cx: Scope) -> Element {
class: "mr-2",
href: "https://github.com/zino-rs/zino/stargazers",
img {
src: "https://img.shields.io/github/stars/photino/zino",
src: "https://img.shields.io/github/stars/photino/zino?style=flat",
}
}
a {
class: "mr-2",
href: "https://github.com/zino-rs/zino/watchers",
img {
src: "https://img.shields.io/github/watchers/photino/zino",
src: "https://img.shields.io/github/watchers/photino/zino?style=flat",
}
}
a {
class: "mr-2",
href: "https://github.com/zino-rs/zino/forks",
img {
src: "https://img.shields.io/github/forks/photino/zino",
src: "https://img.shields.io/github/forks/photino/zino?style=flat",
}
}
a {
Expand Down
10 changes: 5 additions & 5 deletions zino-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ rmp-serde = "1.1.2"
rust_decimal = "1.33.1"
ryu = "1.0.16"
serde_qs = "0.12.0"
serde_yaml = "0.9.29"
serde_yaml = "0.9.30"
sha2 = "0.10.8"
sysinfo = "0.30.3"
task-local-extensions = "0.1.4"
Expand Down Expand Up @@ -261,7 +261,7 @@ version = "4.4.2"
optional = true

[dependencies.opendal]
version = "0.43.0"
version = "0.44.0"
optional = true
default-features = false
features = ["layers-all"]
Expand Down Expand Up @@ -290,11 +290,11 @@ features = [
]

[dependencies.serde]
version = "1.0.193"
version = "1.0.194"
features = ["derive"]

[dependencies.serde_json]
version = "1.0.108"
version = "1.0.110"
features = ["raw_value"]

[dependencies.sm3]
Expand Down Expand Up @@ -363,7 +363,7 @@ features = [
]

[dev-dependencies]
anyhow = "1.0.77"
anyhow = "1.0.79"
arrayvec = "0.7.4"
base64-simd = "0.8.0"
criterion = "0.5.1"
Expand Down
3 changes: 0 additions & 3 deletions zino-core/src/accessor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ impl GlobalAccessor {
if let Some(segments) = config.get_usize("segments") {
builder.segments(segments);
}
if let Some(thread_pool_enabled) = config.get_bool("thread-pool-enabled") {
builder.thread_pool_enabled(thread_pool_enabled);
}
Ok(Operator::new(builder)?.finish())
}
#[cfg(feature = "accessor-mysql")]
Expand Down
38 changes: 37 additions & 1 deletion zino-core/src/extension/toml_table.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use crate::{datetime, extension::TomlValueExt, Map, Uuid};
use std::time::Duration;
use std::{
net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr},
time::Duration,
};
use toml::value::{Array, Table};
use url::{self, Url};

/// Extension trait for [`Table`](toml::Table).
pub trait TomlTableExt {
Expand Down Expand Up @@ -79,6 +83,18 @@ pub trait TomlTableExt {
/// If the `Uuid` is `nil`, it also returns `None`.
fn parse_uuid(&self, key: &str) -> Option<Result<Uuid, uuid::Error>>;

/// Extracts the string corresponding to the key and parses it as `Url`.
fn parse_url(&self, key: &str) -> Option<Result<Url, url::ParseError>>;

/// Extracts the string corresponding to the key and parses it as `IpAddr`.
fn parse_ip(&self, key: &str) -> Option<Result<IpAddr, AddrParseError>>;

/// Extracts the string corresponding to the key and parses it as `Ipv4Addr`.
fn parse_ipv4(&self, key: &str) -> Option<Result<Ipv4Addr, AddrParseError>>;

/// Extracts the string corresponding to the key and parses it as `Ipv6Addr`.
fn parse_ipv6(&self, key: &str) -> Option<Result<Ipv6Addr, AddrParseError>>;

/// Converts `self` to a JSON object.
fn to_map(&self) -> Map;
}
Expand Down Expand Up @@ -210,6 +226,26 @@ impl TomlTableExt for Table {
.map(|s| s.parse())
}

#[inline]
fn parse_url(&self, key: &str) -> Option<Result<Url, url::ParseError>> {
self.get_str(key).map(|s| s.parse())
}

#[inline]
fn parse_ip(&self, key: &str) -> Option<Result<IpAddr, AddrParseError>> {
self.get_str(key).map(|s| s.parse())
}

#[inline]
fn parse_ipv4(&self, key: &str) -> Option<Result<Ipv4Addr, AddrParseError>> {
self.get_str(key).map(|s| s.parse())
}

#[inline]
fn parse_ipv6(&self, key: &str) -> Option<Result<Ipv6Addr, AddrParseError>> {
self.get_str(key).map(|s| s.parse())
}

fn to_map(&self) -> Map {
let mut map = Map::with_capacity(self.len());
for (key, value) in self.iter() {
Expand Down
4 changes: 4 additions & 0 deletions zino-dioxus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ dioxus-router = "0.4.3"
dioxus-free-icons = "0.7.0"
smallvec = "1.11.1"

[dependencies.chrono]
version = "0.4.31"
features = ["serde"]

[dependencies.uuid]
version = "1.6.1"
features = [
Expand Down
41 changes: 39 additions & 2 deletions zino-dioxus/src/extension/form_data.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use dioxus::events::FormData;
use zino_core::{extension::JsonObjectExt, Map, Uuid};
use std::time::Duration;
use zino_core::{
datetime::{self, Date, DateTime, Time},
extension::JsonObjectExt,
Map, Uuid,
};

/// Extension trait for [`FormData`].
pub trait FormDataExt {
Expand All @@ -10,11 +15,23 @@ pub trait FormDataExt {
/// If the `Uuid` is `nil`, it also returns `None`.
fn parse_uuid(&self) -> Option<Result<Uuid, uuid::Error>>;

/// Parses the string value as `Date`.
fn parse_date(&self) -> Option<Result<Date, chrono::format::ParseError>>;

/// Parses the string value as `Time`.
fn parse_time(&self) -> Option<Result<Time, chrono::format::ParseError>>;

/// Parses the string value as `DateTime`.
fn parse_datetime(&self) -> Option<Result<DateTime, chrono::format::ParseError>>;

/// Parses the string value as `Duration`.
fn parse_duration(&self) -> Option<Result<Duration, datetime::ParseDurationError>>;

/// Converts `self` to a JSON object.
fn to_map(&self) -> Map;
}

impl<'a> FormDataExt for FormData {
impl FormDataExt for FormData {
fn get_str(&self) -> Option<&str> {
let value = self.value.as_str();
(!value.is_empty()).then_some(value)
Expand All @@ -27,6 +44,26 @@ impl<'a> FormDataExt for FormData {
.map(|s| s.parse())
}

#[inline]
fn parse_date(&self) -> Option<Result<Date, chrono::format::ParseError>> {
self.get_str().map(|s| s.parse())
}

#[inline]
fn parse_time(&self) -> Option<Result<Time, chrono::format::ParseError>> {
self.get_str().map(|s| s.parse())
}

#[inline]
fn parse_datetime(&self) -> Option<Result<DateTime, chrono::format::ParseError>> {
self.get_str().map(|s| s.parse())
}

#[inline]
fn parse_duration(&self) -> Option<Result<Duration, datetime::ParseDurationError>> {
self.get_str().map(datetime::parse_duration)
}

fn to_map(&self) -> Map {
let values = &self.values;
let mut map = Map::with_capacity(values.len());
Expand Down
101 changes: 101 additions & 0 deletions zino-dioxus/src/form/field.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use crate::{class::Class, format_class};
use dioxus::prelude::*;
use std::borrow::Cow;

/// A container for the form field with a label.
pub fn FormFieldContainer<'a>(cx: Scope<'a, FormFieldContainerProps<'a>>) -> Element {
let class = format_class!(cx, "field is-horizontal");
let field_label_class = format_class!(cx, field_label_class, "field-label");
let field_body_class = format_class!(cx, field_body_class, "field-body");
let label_class = format_class!(cx, label_class, "label");
render! {
div {
class: "{class}",
div {
class: "{field_label_class}",
label {
class: "{label_class}",
"{cx.props.label}"
}
}
div {
class: "{field_body_class}",
&cx.props.children
}
}
}
}

/// The [`FormFieldContainer`] properties struct for the configuration of the component.
#[derive(Props)]
pub struct FormFieldContainerProps<'a> {
/// The class attribute for the component.
#[props(into)]
pub class: Option<Class<'a>>,
/// A class to apply to the field label container.
#[props(into)]
pub field_label_class: Option<Class<'a>>,
/// A class to apply to the field body container.
#[props(into)]
pub field_body_class: Option<Class<'a>>,
/// A class to apply to the `label` element.
#[props(into)]
pub label_class: Option<Class<'a>>,
/// The label content.
#[props(into)]
pub label: Cow<'a, str>,
/// The children to render within the component.
children: Element<'a>,
}

/// A single field with the form control.
pub fn FormField<'a>(cx: Scope<'a, FormFieldProps<'a>>) -> Element {
let class = format_class!(cx, "field");
let control_class = format_class!(cx, control_class, "control");
render! {
div {
class: "{class}",
div {
class: "{control_class}",
&cx.props.children
}
}
}
}

/// The [`FormField`] properties struct for the configuration of the component.
#[derive(Props)]
pub struct FormFieldProps<'a> {
/// The class attribute for the component.
#[props(into)]
pub class: Option<Class<'a>>,
/// A class to apply custom styles.
#[props(into)]
pub control_class: Option<Class<'a>>,
/// The children to render within the component.
children: Element<'a>,
}

/// Grouped fields with the form control.
pub fn FormGroup<'a>(cx: Scope<'a, FormGroupProps<'a>>) -> Element {
let class = format_class!(cx, "field is-grouped");
render! {
div {
class: "{class}",
&cx.props.children
}
}
}

/// The [`FormGroup`] properties struct for the configuration of the component.
#[derive(Props)]
pub struct FormGroupProps<'a> {
/// The class attribute for the component.
#[props(into)]
pub class: Option<Class<'a>>,
/// A class to apply custom styles.
#[props(into)]
pub control_class: Option<Class<'a>>,
/// The children to render within the component.
children: Element<'a>,
}
8 changes: 8 additions & 0 deletions zino-dioxus/src/form/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//! Generic form controls.
mod field;

pub use field::{
FormField, FormFieldContainer, FormFieldContainerProps, FormFieldProps, FormGroup,
FormGroupProps,
};
2 changes: 2 additions & 0 deletions zino-dioxus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@

pub mod class;
pub mod extension;
pub mod form;
pub mod icon;
pub mod layout;
pub mod menu;
pub mod message;
pub mod prelude;
pub mod theme;
pub mod typography;
7 changes: 6 additions & 1 deletion zino-dioxus/src/message/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ pub fn Notification<'a>(cx: Scope<'a, NotificationProps<'a>>) -> Element {
class: "{class}",
button {
class: "{close_class}",
onclick: |_event| {
onclick: move |event| {
if let Some(handler) = cx.props.on_close.as_ref() {
handler.call(event);
}
close_notification.set(true);
}
}
Expand All @@ -33,6 +36,8 @@ pub struct NotificationProps<'a> {
/// A class to apply to the `close` button element.
#[props(into)]
pub close_class: Option<Class<'a>>,
/// An event handler to be called when the `close` button is clicked.
pub on_close: Option<EventHandler<'a, MouseEvent>>,
/// The children to render within the component.
children: Element<'a>,
}
2 changes: 2 additions & 0 deletions zino-dioxus/src/prelude/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub use crate::{
class::Class,
extension::FormDataExt,
form::{FormField, FormFieldContainer, FormGroup},
icon::{Icon, IconText},
layout::{Container, FluidContainer, MainContainer},
menu::{
Expand All @@ -11,4 +12,5 @@ pub use crate::{
},
message::Notification,
theme::Theme,
typography::FixedWidthSpan,
};
5 changes: 5 additions & 0 deletions zino-dioxus/src/typography/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
//! Typography helpers.
mod span;

pub use span::{FixedWidthSpan, FixedWidthSpanProps};
Loading

0 comments on commit 50cb615

Please sign in to comment.