forked from photino/zino
Add more dioxus components
This commit is contained in:
parent
b970f94bfc
commit
4fc633a0ff
22
README.md
22
README.md
|
@ -52,12 +52,12 @@ For Chinese rustaceans, you can also follow our WeChat official account to canta
|
|||
|
||||
![zino-web](https://user-images.githubusercontent.com/3446306/265183253-90b4f8bb-33d2-4e14-b6e3-78da313e2e68.png)
|
||||
|
||||
[`zino-core`]: https://github.com/photino/zino/tree/main/zino-core
|
||||
[`zino-derive`]: https://github.com/photino/zino/tree/main/zino-derive
|
||||
[`zino-model`]: https://github.com/photino/zino/tree/main/zino-model
|
||||
[`zino-extra`]: https://github.com/photino/zino/tree/main/zino-extra
|
||||
[`zino-dioxus`]: https://github.com/photino/zino/tree/main/zino-dioxus
|
||||
[`zino-cli`]: https://github.com/photino/zino/tree/main/zino-cli
|
||||
[`zino-core`]: https://github.com/zino-rs/zino/tree/main/zino-core
|
||||
[`zino-derive`]: https://github.com/zino-rs/zino/tree/main/zino-derive
|
||||
[`zino-model`]: https://github.com/zino-rs/zino/tree/main/zino-model
|
||||
[`zino-extra`]: https://github.com/zino-rs/zino/tree/main/zino-extra
|
||||
[`zino-dioxus`]: https://github.com/zino-rs/zino/tree/main/zino-dioxus
|
||||
[`zino-cli`]: https://github.com/zino-rs/zino/tree/main/zino-cli
|
||||
[zino]: https://crates.io/crates/zino
|
||||
[zino-docs]: https://docs.rs/zino
|
||||
[zino-core]: https://crates.io/crates/zino-core
|
||||
|
@ -78,8 +78,8 @@ For Chinese rustaceans, you can also follow our WeChat official account to canta
|
|||
[`actix-web`]: https://crates.io/crates/actix-web
|
||||
[`axum`]: https://crates.io/crates/axum
|
||||
[`dioxus`]: https://crates.io/crates/dioxus
|
||||
[`actix-app`]: https://github.com/photino/zino/tree/main/examples/actix-app
|
||||
[`axum-app`]: https://github.com/photino/zino/tree/main/examples/axum-app
|
||||
[`dioxus-desktop`]: https://github.com/photino/zino/tree/main/examples/dioxus-desktop
|
||||
[license]: https://github.com/photino/zino/blob/main/LICENSE
|
||||
[zino-issue]: https://github.com/photino/zino/issues/new
|
||||
[`actix-app`]: https://github.com/zino-rs/zino/tree/main/examples/actix-app
|
||||
[`axum-app`]: https://github.com/zino-rs/zino/tree/main/examples/axum-app
|
||||
[`dioxus-desktop`]: https://github.com/zino-rs/zino/tree/main/examples/dioxus-desktop
|
||||
[license]: https://github.com/zino-rs/zino/blob/main/LICENSE
|
||||
[zino-issue]: https://github.com/zino-rs/zino/issues/new
|
||||
|
|
|
@ -5,7 +5,7 @@ An example for [actix-web] integration.
|
|||
|
||||
[actix-web]: https://crates.io/crates/actix-web
|
||||
"""
|
||||
contact = { url = "https://github.com/photino/zino" }
|
||||
contact = { url = "https://github.com/zino-rs/zino" }
|
||||
license = "MIT"
|
||||
|
||||
[security_schemes.jwt_auth]
|
||||
|
|
|
@ -5,7 +5,7 @@ An example for [axum] integration.
|
|||
|
||||
[axum]: https://crates.io/crates/axum
|
||||
"""
|
||||
contact = { url = "https://github.com/photino/zino" }
|
||||
contact = { url = "https://github.com/zino-rs/zino" }
|
||||
license = "MIT"
|
||||
|
||||
[security_schemes.jwt_auth]
|
||||
|
|
|
@ -41,7 +41,7 @@ pub fn Wrapper(cx: Scope) -> Element {
|
|||
}
|
||||
NavbarEnd {
|
||||
NavbarLink {
|
||||
to: "https://github.com/photino/zino",
|
||||
to: "https://github.com/zino-rs/zino",
|
||||
IconText {
|
||||
Icon {
|
||||
SvgIcon { icon: BsGithub }
|
||||
|
|
|
@ -53,7 +53,7 @@ pub fn Overview(cx: Scope) -> Element {
|
|||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/tags",
|
||||
href: "https://github.com/zino-rs/zino/tags",
|
||||
img {
|
||||
src: "https://img.shields.io/github/v/tag/photino/zino",
|
||||
}
|
||||
|
@ -68,56 +68,56 @@ pub fn Overview(cx: Scope) -> Element {
|
|||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/stargazers",
|
||||
href: "https://github.com/zino-rs/zino/stargazers",
|
||||
img {
|
||||
src: "https://img.shields.io/github/stars/photino/zino",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/watchers",
|
||||
href: "https://github.com/zino-rs/zino/watchers",
|
||||
img {
|
||||
src: "https://img.shields.io/github/watchers/photino/zino",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/forks",
|
||||
href: "https://github.com/zino-rs/zino/forks",
|
||||
img {
|
||||
src: "https://img.shields.io/github/forks/photino/zino",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/graphs/contributors",
|
||||
href: "https://github.com/zino-rs/zino/graphs/contributors",
|
||||
img {
|
||||
src: "https://img.shields.io/github/contributors/photino/zino",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/commits/main",
|
||||
href: "https://github.com/zino-rs/zino/commits/main",
|
||||
img {
|
||||
src: "https://img.shields.io/github/last-commit/photino/zino/main",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/pulls",
|
||||
href: "https://github.com/zino-rs/zino/pulls",
|
||||
img {
|
||||
src: "https://img.shields.io/github/issues-pr/photino/zino"
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/actions/workflows/rust.yml",
|
||||
href: "https://github.com/zino-rs/zino/actions/workflows/rust.yml",
|
||||
img {
|
||||
src: "https://img.shields.io/github/actions/workflow/status/photino/zino/rust.yml",
|
||||
}
|
||||
}
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/blob/main/LICENSE",
|
||||
href: "https://github.com/zino-rs/zino/blob/main/LICENSE",
|
||||
img {
|
||||
src: "https://img.shields.io/github/license/photino/zino",
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ pub fn Overview(cx: Scope) -> Element {
|
|||
class: "card-content",
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/issues",
|
||||
href: "https://github.com/zino-rs/zino/issues",
|
||||
img {
|
||||
src: "https://img.shields.io/github/issues/photino/zino",
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ pub fn Overview(cx: Scope) -> Element {
|
|||
for label in ["bug", "enhancement", "dependencies"] {
|
||||
a {
|
||||
class: "mr-2",
|
||||
href: "https://github.com/photino/zino/labels/{label}",
|
||||
href: "https://github.com/zino-rs/zino/labels/{label}",
|
||||
img {
|
||||
src: "https://img.shields.io/github/issues/photino/zino/{label}",
|
||||
}
|
||||
|
|
|
@ -309,7 +309,7 @@ fn StargazerListing<'a>(cx: Scope<'a>, index: usize, stargazer: &'a Map) -> Elem
|
|||
img { src: avatar_url },
|
||||
}
|
||||
}
|
||||
th {
|
||||
td {
|
||||
a {
|
||||
href: "https://github.com/{name}?tab=followers",
|
||||
img {
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["command-line-utilities", "network-programming", "web-programming"]
|
||||
keywords = ["cli", "gui", "zino", "dioxus"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-cli"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-cli)
|
||||
[![docs-rs]](https://docs.rs/zino-cli)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
CLI tools for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming::http-server"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-core"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-core)
|
||||
[![docs-rs]](https://docs.rs/zino-core)
|
||||
|
||||
|
@ -28,7 +28,7 @@ The following optional features are available:
|
|||
| `validator` | Enables the common validation rules. | No |
|
||||
| `view` | Enables the HTML template rendering. | No |
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
[`opendal`]: https://crates.io/crates/opendal
|
||||
[`metrics`]: https://crates.io/crates/metrics
|
||||
[`async-std`]: https://crates.io/crates/async-std
|
||||
|
|
|
@ -229,6 +229,9 @@ pub trait JsonObjectExt {
|
|||
/// Creates a new instance with the `entries`.
|
||||
fn data_entries(values: Vec<Map>) -> Self;
|
||||
|
||||
/// Creates a new instance with a single key `item`.
|
||||
fn data_item(value: impl Into<JsonValue>) -> Self;
|
||||
|
||||
/// Creates a new instance with the `items`.
|
||||
fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Self;
|
||||
}
|
||||
|
@ -685,6 +688,13 @@ impl JsonObjectExt for Map {
|
|||
map
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn data_item(value: impl Into<JsonValue>) -> Self {
|
||||
let mut map = Map::with_capacity(1);
|
||||
map.insert("item".to_owned(), value.into());
|
||||
map
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn data_items<T: Into<JsonValue>>(values: Vec<T>) -> Self {
|
||||
let mut map = Map::with_capacity(2);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{datetime, extension::TomlValueExt, Map};
|
||||
use crate::{datetime, extension::TomlValueExt, Map, Uuid};
|
||||
use std::time::Duration;
|
||||
use toml::value::{Array, Table};
|
||||
|
||||
|
@ -75,6 +75,10 @@ pub trait TomlTableExt {
|
|||
/// and parses it as `Duration`.
|
||||
fn get_duration(&self, key: &str) -> Option<Duration>;
|
||||
|
||||
/// Extracts the string corresponding to the key and parses it as `Uuid`.
|
||||
/// If the `Uuid` is `nil`, it also returns `None`.
|
||||
fn parse_uuid(&self, key: &str) -> Option<Result<Uuid, uuid::Error>>;
|
||||
|
||||
/// Converts `self` to a JSON object.
|
||||
fn to_map(&self) -> Map;
|
||||
}
|
||||
|
@ -199,6 +203,13 @@ impl TomlTableExt for Table {
|
|||
.and_then(|s| datetime::parse_duration(s).ok())
|
||||
}
|
||||
|
||||
fn parse_uuid(&self, key: &str) -> Option<Result<Uuid, uuid::Error>> {
|
||||
self.get_str(key)
|
||||
.map(|s| s.trim_start_matches("urn:uuid:"))
|
||||
.filter(|s| !s.chars().all(|c| c == '0' || c == '-'))
|
||||
.map(|s| s.parse())
|
||||
}
|
||||
|
||||
fn to_map(&self) -> Map {
|
||||
let mut map = Map::with_capacity(self.len());
|
||||
for (key, value) in self.iter() {
|
||||
|
|
|
@ -62,6 +62,9 @@ pub type TomlValue = toml::Value;
|
|||
/// A Universally Unique Identifier (UUID).
|
||||
pub type Uuid = uuid::Uuid;
|
||||
|
||||
/// A 128 bit representation of a fixed-precision decimal number.
|
||||
pub type Decimal = rust_decimal::Decimal;
|
||||
|
||||
/// A value which is initialized on the first access.
|
||||
pub type LazyLock<T> = once_cell::sync::Lazy<T>;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use super::{DatabaseDriver, DatabaseRow};
|
||||
use crate::{error::Error, BoxError};
|
||||
use crate::{error::Error, BoxError, Decimal, Uuid};
|
||||
use chrono::{DateTime, Local, NaiveDate, NaiveTime};
|
||||
use sqlx::{database::HasValueRef, Database, Decode, Row, Type};
|
||||
|
||||
|
@ -78,12 +78,54 @@ where
|
|||
row.try_get_unchecked(field).map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Decodes a single value as `Decimal` for the field in a row.
|
||||
#[cfg(any(
|
||||
feature = "orm-mariadb",
|
||||
feature = "orm-mysql",
|
||||
feature = "orm-postgres",
|
||||
feature = "orm-tidb"
|
||||
))]
|
||||
#[inline]
|
||||
pub fn decode_decimal(row: &DatabaseRow, field: &str) -> Result<Decimal, Error> {
|
||||
row.try_get_unchecked(field).map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Decodes a single value as `Decimal` for the field in a row.
|
||||
#[cfg(not(any(
|
||||
feature = "orm-mariadb",
|
||||
feature = "orm-mysql",
|
||||
feature = "orm-postgres",
|
||||
feature = "orm-tidb"
|
||||
)))]
|
||||
#[inline]
|
||||
pub fn decode_decimal(row: &DatabaseRow, field: &str) -> Result<Decimal, Error> {
|
||||
decode::<String>(row, field)
|
||||
.and_then(|value| value.parse().map_err(Error::from))
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Decodes a single value as `Uuid` for the field in a row.
|
||||
#[cfg(feature = "orm-postgres")]
|
||||
#[inline]
|
||||
pub fn decode_uuid(row: &DatabaseRow, field: &str) -> Result<Uuid, Error> {
|
||||
row.try_get_unchecked(field).map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Decodes a single value as `Uuid` for the field in a row.
|
||||
#[cfg(not(feature = "orm-postgres"))]
|
||||
#[inline]
|
||||
pub fn decode_uuid(row: &DatabaseRow, field: &str) -> Result<Uuid, Error> {
|
||||
decode::<String>(row, field)
|
||||
.and_then(|value| value.parse().map_err(Error::from))
|
||||
.map_err(Error::from)
|
||||
}
|
||||
|
||||
/// Decodes a single value as `Vec<T>` for the field in a row.
|
||||
#[cfg(feature = "orm-postgres")]
|
||||
#[inline]
|
||||
pub fn decode_array<'r, T>(row: &'r sqlx::postgres::PgRow, field: &str) -> Result<Vec<T>, Error>
|
||||
pub fn decode_array<'r, T>(row: &'r DatabaseRow, field: &str) -> Result<Vec<T>, Error>
|
||||
where
|
||||
T: for<'a> Decode<'a, sqlx::Postgres> + sqlx::Type<sqlx::Postgres>,
|
||||
T: for<'a> Decode<'a, DatabaseDriver> + sqlx::Type<DatabaseDriver>,
|
||||
{
|
||||
row.try_get_unchecked(field).map_err(Error::from)
|
||||
}
|
||||
|
|
|
@ -87,19 +87,19 @@ macro_rules! impl_sqlx_executor {
|
|||
let mut stream = sqlx::query(sql).fetch(self);
|
||||
let mut max_rows = super::MAX_ROWS.load(Relaxed);
|
||||
let mut rows = Vec::with_capacity(stream.size_hint().0.min(max_rows));
|
||||
while max_rows > 0 {
|
||||
match stream.next().await {
|
||||
Some(Ok(row)) => {
|
||||
while let Some(result) = stream.next().await {
|
||||
match result {
|
||||
Ok(row) if max_rows > 0 => {
|
||||
rows.push(row);
|
||||
max_rows -= 1;
|
||||
}
|
||||
Some(Err(err)) => {
|
||||
Err(err) => {
|
||||
if matches!(err, sqlx::error::Error::PoolTimedOut) {
|
||||
super::GlobalPool::connect_all().await;
|
||||
}
|
||||
return Err(err.into());
|
||||
}
|
||||
None => break,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
Ok(rows)
|
||||
|
@ -121,19 +121,19 @@ macro_rules! impl_sqlx_executor {
|
|||
let mut stream = query.fetch(self);
|
||||
let mut max_rows = super::MAX_ROWS.load(Relaxed);
|
||||
let mut rows = Vec::with_capacity(stream.size_hint().0.min(max_rows));
|
||||
while max_rows > 0 {
|
||||
match stream.next().await {
|
||||
Some(Ok(row)) => {
|
||||
while let Some(result) = stream.next().await {
|
||||
match result {
|
||||
Ok(row) if max_rows > 0 => {
|
||||
rows.push(row);
|
||||
max_rows -= 1;
|
||||
}
|
||||
Some(Err(err)) => {
|
||||
Err(err) => {
|
||||
if matches!(err, sqlx::error::Error::PoolTimedOut) {
|
||||
super::GlobalPool::connect_all().await;
|
||||
}
|
||||
return Err(err.into());
|
||||
}
|
||||
None => break,
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
Ok(rows)
|
||||
|
|
|
@ -137,7 +137,7 @@ mod decode;
|
|||
mod scalar;
|
||||
|
||||
#[cfg(feature = "orm-sqlx")]
|
||||
pub use decode::{decode, decode_array};
|
||||
pub use decode::{decode, decode_array, decode_decimal, decode_uuid};
|
||||
#[cfg(feature = "orm-sqlx")]
|
||||
pub use scalar::ScalarQuery;
|
||||
|
||||
|
|
|
@ -53,8 +53,8 @@ where
|
|||
let mut rows = sqlx::query(&sql).fetch(pool);
|
||||
let mut data = Vec::new();
|
||||
let mut max_rows = super::MAX_ROWS.load(Relaxed);
|
||||
while max_rows > 0 {
|
||||
if let Some(row) = rows.try_next().await? {
|
||||
while let Some(row) = rows.try_next().await? {
|
||||
if max_rows > 0 {
|
||||
data.push(row.try_get_unchecked(0)?);
|
||||
max_rows -= 1;
|
||||
} else {
|
||||
|
@ -109,8 +109,8 @@ where
|
|||
let mut rows = query.fetch(pool);
|
||||
let mut data = Vec::new();
|
||||
let mut max_rows = super::MAX_ROWS.load(Relaxed);
|
||||
while max_rows > 0 {
|
||||
if let Some(row) = rows.try_next().await? {
|
||||
while let Some(row) = rows.try_next().await? {
|
||||
if max_rows > 0 {
|
||||
data.push(row.try_get_unchecked(0)?);
|
||||
max_rows -= 1;
|
||||
} else {
|
||||
|
|
|
@ -512,7 +512,7 @@ pub trait Schema: 'static + Send + Sync + ModelHooks {
|
|||
Self::before_mutation(query, mutation).await?;
|
||||
|
||||
let primary_key_name = Self::PRIMARY_KEY_NAME;
|
||||
let table_name = query.format_table_name::<Self>();
|
||||
let table_name = Self::table_name();
|
||||
let filters = query.format_filters::<Self>();
|
||||
let updates = mutation.format_updates::<Self>();
|
||||
let sql = if cfg!(any(
|
||||
|
@ -557,7 +557,7 @@ pub trait Schema: 'static + Send + Sync + ModelHooks {
|
|||
let pool = Self::acquire_writer().await?.pool();
|
||||
Self::before_mutation(query, mutation).await?;
|
||||
|
||||
let table_name = query.format_table_name::<Self>();
|
||||
let table_name = Self::table_name();
|
||||
let filters = query.format_filters::<Self>();
|
||||
let updates = mutation.format_updates::<Self>();
|
||||
let sql = format!("UPDATE {table_name} SET {updates} {filters};");
|
||||
|
|
|
@ -21,6 +21,9 @@ impl<'c> EncodeColumn<DatabaseDriver> for Column<'c> {
|
|||
"u64" | "i64" | "usize" | "isize" | "Option<u64>" | "Option<i64>" | "u32" | "i32"
|
||||
| "u16" | "i16" | "u8" | "i8" | "Option<u32>" | "Option<i32>" => "INTEGER",
|
||||
"f64" | "f32" => "REAL",
|
||||
"Date" => "DATE",
|
||||
"Time" => "TIME",
|
||||
"DateTime" => "DATETIME",
|
||||
"Vec<u8>" => "BLOB",
|
||||
_ => "TEXT",
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ where
|
|||
let mutation = mutations.0;
|
||||
Self::before_mutation(query, mutation).await?;
|
||||
|
||||
let table_name = query.format_table_name::<Self>();
|
||||
let table_name = Self::table_name();
|
||||
let filters = query.format_filters::<Self>();
|
||||
let updates = mutation.format_updates::<Self>();
|
||||
let sql = format!("UPDATE {table_name} SET {updates} {filters};");
|
||||
|
@ -190,7 +190,7 @@ where
|
|||
let mutation = mutations.1;
|
||||
S::before_mutation(query, mutation).await?;
|
||||
|
||||
let table_name = query.format_table_name::<S>();
|
||||
let table_name = S::table_name();
|
||||
let filters = query.format_filters::<S>();
|
||||
let updates = mutation.format_updates::<S>();
|
||||
let sql = format!("UPDATE {table_name} SET {updates} {filters};");
|
||||
|
|
|
@ -5,8 +5,8 @@ version = "0.15.0"
|
|||
rust-version = "1.75"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-derive"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-derive)
|
||||
[![docs-rs]](https://docs.rs/zino-derive)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
Derived traits for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -28,7 +28,15 @@ pub(super) fn parse_token_stream(input: DeriveInput) -> TokenStream {
|
|||
if ignore {
|
||||
continue;
|
||||
}
|
||||
if type_name == "Map" {
|
||||
if type_name == "Uuid" {
|
||||
decode_model_fields.push(quote! {
|
||||
model.#ident = orm::decode_uuid(row, #name)?;
|
||||
});
|
||||
} else if type_name == "Decimal" {
|
||||
decode_model_fields.push(quote! {
|
||||
model.#ident = orm::decode_decimal(row, #name)?;
|
||||
});
|
||||
} else if type_name == "Map" {
|
||||
decode_model_fields.push(quote! {
|
||||
if let JsonValue::Object(map) = orm::decode(row, #name)? {
|
||||
model.#ident = map;
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["gui", "network-programming", "web-programming"]
|
||||
keywords = ["zino", "dioxus", "components"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-dioxus"
|
||||
readme = "README.md"
|
||||
|
||||
|
@ -19,6 +19,15 @@ dioxus-router = "0.4.3"
|
|||
dioxus-free-icons = "0.7.0"
|
||||
smallvec = "1.11.1"
|
||||
|
||||
[dependencies.uuid]
|
||||
version = "1.6.1"
|
||||
features = [
|
||||
"fast-rng",
|
||||
"serde",
|
||||
"v4",
|
||||
"v7",
|
||||
]
|
||||
|
||||
[dependencies.zino-core]
|
||||
path = "../zino-core"
|
||||
version = "0.18.0"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-dioxus)
|
||||
[![docs-rs]](https://docs.rs/zino-dioxus)
|
||||
|
||||
|
@ -12,7 +12,7 @@ Dioxus components for [`zino`].
|
|||
|
||||
The design of our components is most inspired by [`Bulma`] and [`daisyUI`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
[`Bulma`]: https://bulma.io/
|
||||
[`daisyUI`]: https://daisyui.com/
|
||||
|
||||
|
|
|
@ -149,4 +149,11 @@ macro_rules! format_class {
|
|||
.map(Class::format)
|
||||
.unwrap_or_else(|| $default_class.into())
|
||||
};
|
||||
($cx:ident, $class_prop:ident, $default_class:expr) => {
|
||||
$cx.props
|
||||
.$class_prop
|
||||
.as_ref()
|
||||
.map(Class::format)
|
||||
.unwrap_or_else(|| $default_class.into())
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
use dioxus::events::FormData;
|
||||
use zino_core::{extension::JsonObjectExt, Map, Uuid};
|
||||
|
||||
/// Extension trait for [`FormData`].
|
||||
pub trait FormDataExt {
|
||||
/// Extracts the string value.
|
||||
fn get_str(&self) -> Option<&str>;
|
||||
|
||||
/// Extracts the string value and parses it as `Uuid`.
|
||||
/// If the `Uuid` is `nil`, it also returns `None`.
|
||||
fn parse_uuid(&self) -> Option<Result<Uuid, uuid::Error>>;
|
||||
|
||||
/// Converts `self` to a JSON object.
|
||||
fn to_map(&self) -> Map;
|
||||
}
|
||||
|
||||
impl<'a> FormDataExt for FormData {
|
||||
fn get_str(&self) -> Option<&str> {
|
||||
let value = self.value.as_str();
|
||||
(!value.is_empty()).then_some(value)
|
||||
}
|
||||
|
||||
fn parse_uuid(&self) -> Option<Result<Uuid, uuid::Error>> {
|
||||
self.get_str()
|
||||
.map(|s| s.trim_start_matches("urn:uuid:"))
|
||||
.filter(|s| !s.chars().all(|c| c == '0' || c == '-'))
|
||||
.map(|s| s.parse())
|
||||
}
|
||||
|
||||
fn to_map(&self) -> Map {
|
||||
let values = &self.values;
|
||||
let mut map = Map::with_capacity(values.len());
|
||||
for (key, value) in values.iter() {
|
||||
if let Some([value]) = values.get(key).map(|v| v.as_slice()) {
|
||||
map.upsert(key, value.clone());
|
||||
} else {
|
||||
map.upsert(key, value.clone());
|
||||
}
|
||||
}
|
||||
map
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
//! Extension traits and helper utilities.
|
||||
|
||||
mod form_data;
|
||||
mod vnode;
|
||||
|
||||
pub use form_data::FormDataExt;
|
||||
pub use vnode::VNodeExt;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use dioxus_core::{DynamicNode::Component, VNode};
|
||||
|
||||
/// Extension trait for [`VNode`](dioxus_core::VNode).
|
||||
/// Extension trait for [`VNode`].
|
||||
pub trait VNodeExt {
|
||||
/// Returns `true` if `self` has a given component node as its child.
|
||||
fn has_component(&self, name: &str) -> bool;
|
||||
|
|
|
@ -9,5 +9,6 @@ pub mod extension;
|
|||
pub mod icon;
|
||||
pub mod layout;
|
||||
pub mod menu;
|
||||
pub mod message;
|
||||
pub mod prelude;
|
||||
pub mod theme;
|
||||
|
|
|
@ -7,7 +7,7 @@ mod sidebar;
|
|||
pub use dropdown::{Dropdown, DropdownProps};
|
||||
pub use navbar::{
|
||||
Navbar, NavbarBrand, NavbarBrandProps, NavbarCenter, NavbarCenterProps, NavbarEnd,
|
||||
NavbarEndProps, NavbarLink, NavbarLinkProps, NavbarMenu, NavbarMenuProps, NavbarProps,
|
||||
NavbarStart, NavbarStartProps,
|
||||
NavbarEndProps, NavbarItem, NavbarItemProps, NavbarLink, NavbarLinkProps, NavbarMenu,
|
||||
NavbarMenuProps, NavbarProps, NavbarStart, NavbarStartProps,
|
||||
};
|
||||
pub use sidebar::{Sidebar, SidebarProps};
|
||||
|
|
|
@ -169,3 +169,24 @@ pub struct NavbarLinkProps<'a> {
|
|||
/// The children to render within the component.
|
||||
children: Element<'a>,
|
||||
}
|
||||
|
||||
/// A container for each single item of the navbar.
|
||||
pub fn NavbarItem<'a>(cx: Scope<'a, NavbarItemProps<'a>>) -> Element {
|
||||
let class = format_class!(cx, "navbar-item");
|
||||
render! {
|
||||
div {
|
||||
class: "{class}",
|
||||
&cx.props.children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`NavbarItem`] properties struct for the configuration of the component.
|
||||
#[derive(Props)]
|
||||
pub struct NavbarItemProps<'a> {
|
||||
/// The class attribute for the component.
|
||||
#[props(into)]
|
||||
pub class: Option<Class<'a>>,
|
||||
/// The children to render within the component.
|
||||
children: Element<'a>,
|
||||
}
|
||||
|
|
|
@ -1,16 +1,23 @@
|
|||
use crate::theme::Theme;
|
||||
use crate::{class::Class, format_class};
|
||||
use dioxus::prelude::*;
|
||||
|
||||
/// A vertical menu used in the navigation aside.
|
||||
pub fn Sidebar<'a>(cx: Scope<'a, SidebarProps<'a>>) -> Element {
|
||||
let class = format_class!(cx, "sidebar");
|
||||
render! {
|
||||
div {}
|
||||
div {
|
||||
class: "{class}",
|
||||
&cx.props.children
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`Sidebar`] properties struct for the configuration of the component.
|
||||
#[derive(Debug, PartialEq, Props)]
|
||||
#[derive(Props)]
|
||||
pub struct SidebarProps<'a> {
|
||||
/// Theme.
|
||||
theme: &'a Theme,
|
||||
/// The class attribute for the component.
|
||||
#[props(into)]
|
||||
pub class: Option<Class<'a>>,
|
||||
/// The children to render within the component.
|
||||
children: Element<'a>,
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
//! Contextual feedback messages.
|
||||
|
||||
mod notification;
|
||||
|
||||
pub use notification::{Notification, NotificationProps};
|
|
@ -0,0 +1,38 @@
|
|||
use crate::{class::Class, format_class};
|
||||
use dioxus::prelude::*;
|
||||
|
||||
/// A simple colored block meant to draw the attention to the user about something.
|
||||
pub fn Notification<'a>(cx: Scope<'a, NotificationProps<'a>>) -> Element {
|
||||
let close_notification = use_state(cx, || false);
|
||||
if *close_notification.get() {
|
||||
None
|
||||
} else {
|
||||
let class = format_class!(cx, "notification");
|
||||
let close_class = format_class!(cx, close_class, "delete");
|
||||
render! {
|
||||
div {
|
||||
class: "{class}",
|
||||
button {
|
||||
class: "{close_class}",
|
||||
onclick: |_event| {
|
||||
close_notification.set(true);
|
||||
}
|
||||
}
|
||||
&cx.props.children
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The [`Notification`] properties struct for the configuration of the component.
|
||||
#[derive(Props)]
|
||||
pub struct NotificationProps<'a> {
|
||||
/// The class attribute for the component.
|
||||
#[props(into)]
|
||||
pub class: Option<Class<'a>>,
|
||||
/// A class to apply to the `close` button element.
|
||||
#[props(into)]
|
||||
pub close_class: Option<Class<'a>>,
|
||||
/// The children to render within the component.
|
||||
children: Element<'a>,
|
||||
}
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
pub use crate::{
|
||||
class::Class,
|
||||
extension::FormDataExt,
|
||||
icon::{Icon, IconText},
|
||||
layout::{Container, FluidContainer, MainContainer},
|
||||
menu::{
|
||||
Dropdown, Navbar, NavbarBrand, NavbarCenter, NavbarEnd, NavbarLink, NavbarMenu,
|
||||
Dropdown, Navbar, NavbarBrand, NavbarCenter, NavbarEnd, NavbarItem, NavbarLink, NavbarMenu,
|
||||
NavbarStart, Sidebar,
|
||||
},
|
||||
message::Notification,
|
||||
theme::Theme,
|
||||
};
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-extra"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-extra)
|
||||
[![docs-rs]](https://docs.rs/zino-extra)
|
||||
|
||||
|
@ -17,4 +17,4 @@ The following optional features are available:
|
|||
| `cache` | Enables the cache services. | No |
|
||||
| `format` | Enables the support for common file formats. | No |
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-middleware"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-middleware)
|
||||
[![docs-rs]](https://docs.rs/zino-middleware)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
Middlewares for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["web-programming", "database"]
|
||||
keywords = ["web", "model", "orm", "schema"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-model"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-model)
|
||||
[![docs-rs]](https://docs.rs/zino-model)
|
||||
|
||||
|
@ -8,5 +8,5 @@
|
|||
|
||||
Domain models for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-router"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-router)
|
||||
[![docs-rs]](https://docs.rs/zino-router)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
A flexible router for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-rpc"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-rpc)
|
||||
[![docs-rs]](https://docs.rs/zino-rpc)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
RPC support for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino-server"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino-server)
|
||||
[![docs-rs]](https://docs.rs/zino-server)
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
|||
|
||||
A HTTP server for [`zino`].
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
license = "MIT"
|
||||
categories = ["asynchronous", "network-programming", "web-programming::http-server"]
|
||||
keywords = ["http", "web", "framework"]
|
||||
homepage = "https://github.com/photino/zino"
|
||||
repository = "https://github.com/photino/zino"
|
||||
homepage = "https://github.com/zino-rs/zino"
|
||||
repository = "https://github.com/zino-rs/zino"
|
||||
documentation = "https://docs.rs/zino"
|
||||
readme = "README.md"
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
[![github]](https://github.com/photino/zino)
|
||||
[![github]](https://github.com/zino-rs/zino)
|
||||
[![crates-io]](https://crates.io/crates/zino)
|
||||
[![docs-rs]](https://docs.rs/zino)
|
||||
|
||||
|
@ -38,13 +38,13 @@ The following optional features are available:
|
|||
| `orm` | Enables the ORM for MySQL, PostgreSQL or **SQLite**. | Yes |
|
||||
| `view` | Enables the HTML template rendering. | Yes |
|
||||
|
||||
[`zino`]: https://github.com/photino/zino
|
||||
[`zino`]: https://github.com/zino-rs/zino
|
||||
[`sqlx`]: https://crates.io/crates/sqlx
|
||||
[`tracing`]: https://crates.io/crates/tracing
|
||||
[`metrics`]: https://crates.io/crates/metrics
|
||||
[`actix-web`]: https://crates.io/crates/actix-web
|
||||
[`axum`]: https://crates.io/crates/axum
|
||||
[`dioxus`]: https://crates.io/crates/dioxus
|
||||
[`actix-app`]: https://github.com/photino/zino/tree/main/examples/actix-app
|
||||
[`axum-app`]: https://github.com/photino/zino/tree/main/examples/axum-app
|
||||
[`dioxus-desktop`]: https://github.com/photino/zino/tree/main/examples/dioxus-desktop
|
||||
[`actix-app`]: https://github.com/zino-rs/zino/tree/main/examples/actix-app
|
||||
[`axum-app`]: https://github.com/zino-rs/zino/tree/main/examples/axum-app
|
||||
[`dioxus-desktop`]: https://github.com/zino-rs/zino/tree/main/examples/dioxus-desktop
|
||||
|
|
|
@ -56,6 +56,9 @@ where
|
|||
}
|
||||
});
|
||||
}
|
||||
runtime.block_on(async {
|
||||
Self::load().await;
|
||||
});
|
||||
|
||||
let app_env = Self::env();
|
||||
let app_name = Self::name();
|
||||
|
|
|
@ -21,7 +21,7 @@ pub use zino_core::{
|
|||
schedule::{AsyncCronJob, AsyncJob, AsyncJobScheduler, CronJob, Job, JobScheduler},
|
||||
state::State,
|
||||
validation::Validation,
|
||||
warn, BoxFuture, LazyLock, Map, Record, Uuid,
|
||||
warn, BoxFuture, Decimal, LazyLock, Map, Record, Uuid,
|
||||
};
|
||||
|
||||
#[cfg(feature = "orm")]
|
||||
|
|
Loading…
Reference in New Issue