Nutype adalah makro proc yang memungkinkan penambahan kendala tambahan seperti sanitasi dan validasi ke pola newType biasa. Kode yang dihasilkan membuat mustahil untuk instantiate nilai tanpa melewati cek. Ini bekerja dengan cara ini bahkan dengan deserialisasi serde .
use nutype :: nutype ;
// Define newtype Username
# [ nutype (
sanitize ( trim , lowercase ) ,
validate ( not_empty , len_char_max = 20 ) ,
derive ( Debug , PartialEq , Clone ) ,
) ]
pub struct Username ( String ) ;
// We can obtain a value of Username with `::try_new()`.
// Note that Username holds a sanitized string
assert_eq ! (
Username :: try_new ( " FooBar " ) . unwrap ( ) . into_inner ( ) ,
"foobar"
) ;
// It's impossible to obtain an invalid Username
// Note that we also got `UsernameError` enum generated implicitly
// based on the validation rules.
assert_eq ! (
Username :: try_new ( " " ) ,
Err ( UsernameError :: NotEmptyViolated ) ,
) ;
assert_eq ! (
Username :: try_new ( "TheUserNameIsVeryVeryLong" ) ,
Err ( UsernameError :: LenCharMaxViolated ) ,
) ;Untuk lebih lanjut, silakan lihat:
Sanitizer, validator, dan ciri -ciri yang dapat ditentukan ditentukan oleh tipe bagian dalam, yang termasuk dalam kategori berikut:
u8 , u16 , u32 , u64 , u128 , i8 , i16 , i32 , i64 , i128 , usize , isize )f32 , f64 ) Saat ini tipe string dalam hanya mendukung tipe String (dimiliki).
| Pembersih | Keterangan | Contoh |
|---|---|---|
trim | Menghapus ruang putih terkemuka dan membuntuti | trim |
lowercase | Mengubah string menjadi huruf kecil | lowercase |
uppercase | Mengubah string menjadi huruf besar | uppercase |
with | Pembersih Kustom. Fungsi atau penutupan yang menerima String dan mengembalikan String | with = |mut s: String| ( s.truncate(5); s ) |
| Validator | Keterangan | Varian kesalahan | Contoh |
|---|---|---|---|
len_char_min | Panjang string min (dalam karakter, bukan byte) | LenCharMinViolated | len_char_min = 5 |
len_char_max | Panjang maksimal string (dalam chars, bukan byte) | LenCharMaxViolated | len_char_max = 255 |
not_empty | Menolak string kosong | NotEmptyViolated | not_empty |
regex | Memvalidasi format dengan regex. Membutuhkan fitur regex . | RegexViolated | regex = "^[0-9]{7}$" atau regex = ID_REGEX |
predicate | Validator khusus. Fungsi atau penutupan yang menerima &str dan mengembalikan bool | PredicateViolated | predicate = |s: &str| s.contains('@') |
with | Validator khusus dengan kesalahan khusus | N/a | (Lihat contoh di bawah) |
Persyaratan:
regex dari nutype diaktifkan.regex sebagai ketergantungan.Ada sejumlah cara Anda dapat menggunakan Regex.
Ekspresi reguler dapat didefinisikan tepat di tempat:
# [ nutype ( validate ( regex = "^[0-9]{3}-[0-9]{3}$" ) ) ]
pub struct PhoneNumber ( String ) ; atau dapat didefinisikan dengan std::sync::LazyLock :
use regex :: Regex ;
static PHONE_NUMBER_REGEX : LazyLock < Regex > = LazyLock :: new ( || Regex :: new ( "^[0-9]{3}-[0-9]{3}$" ) . unwrap ( ) ) ;
# [ nutype ( validate ( regex = PHONE_NUMBER_REGEX ) ) ]
pub struct PhoneNumber ( String ) ; atau dapat didefinisikan dengan lazy_static :
use lazy_static :: lazy_static ;
use regex :: Regex ;
lazy_static ! {
static ref PHONE_NUMBER_REGEX : Regex = Regex :: new ( "^[0-9]{3}-[0-9]{3}$" ) . unwrap ( ) ;
}
# [ nutype ( validate ( regex = PHONE_NUMBER_REGEX ) ) ]
pub struct PhoneNumber ( String ) ; atau once_cell :
use once_cell :: sync :: Lazy ;
use regex :: Regex ;
static PHONE_NUMBER_REGEX : Lazy < Regex > =
Lazy :: new ( || Regex :: new ( "[0-9]{3}-[0-9]{3}$" ) . unwrap ( ) ) ;
# [ nutype ( validate ( regex = PHONE_NUMBER_REGEX ) ) ]
pub struct PhoneNumber ( String ) ; Ciri-ciri berikut dapat diturunkan untuk tipe berbasis string: Debug , Clone , PartialEq , Eq , PartialOrd , Ord , FromStr , AsRef , Deref , From , TryFrom dari, Into , Hash , Borrow , Display , Default , Serialize , Deserialize .
Jenis batin integer adalah: u8 , u16 , u32 , u64 , u128 , i8 , i16 , i32 , i64 , i128 , usize , isize .
| Pembersih | Keterangan | Contoh |
|---|---|---|
with | Pembersih Kustom. | with = |raw| raw.clamp(0, 100) |
| Validator | Keterangan | Varian kesalahan | Contoh |
|---|---|---|---|
less | Batas atas eksklusif | LessViolated | less = 100 |
less_or_equal | Bound atas inklusif | LessOrEqualViolated | less_or_equal = 99 |
greater | Batas Bawah Eksklusif | GreaterViolated | greater = 17 |
greater_or_equal | Batas bawah inklusif | GreaterOrEqualViolated | greater_or_equal = 18 |
predicate | Predikat khusus | PredicateViolated | predicate = |num| num % 2 == 0 |
with | Validator khusus dengan kesalahan khusus | N/a | (Lihat contoh di bawah) |
Ciri-ciri berikut dapat diturunkan untuk tipe berbasis integer: Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , FromStr , AsRef , Deref , Into , From , TryFrom , Hash , Borrow , Display , Default , Serialize , Deserialize .
Jenis batin float adalah: f32 , f64 .
| Pembersih | Keterangan | Contoh |
|---|---|---|
with | Pembersih Kustom. | with = |val| val.clamp(0.0, 100.0) |
| Validator | Keterangan | Varian kesalahan | Contoh |
|---|---|---|---|
less | Batas atas eksklusif | LessViolated | less = 100.0 |
less_or_equal | Bound atas inklusif | LessOrEqualViolated | less_or_equal = 100.0 |
greater | Batas Bawah Eksklusif | GreaterViolated | greater = 0.0 |
greater_or_equal | Batas bawah inklusif | GreaterOrEqualViolated | greater_or_equal = 0.0 |
finite | Periksa melawan Nan dan Infinity | FiniteViolated | finite |
predicate | Predikat khusus | PredicateViolated | predicate = |val| val != 50.0 |
with | Validator khusus dengan kesalahan khusus | N/a | (Lihat contoh di bawah) |
Ciri-ciri berikut dapat diturunkan untuk tipe berbasis float: Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , FromStr , AsRef , Deref , Into , From , TryFrom , Hash , Borrow , Display , Default , Serialize , Deserialize .
Dimungkinkan juga untuk mendapatkan Eq dan Ord jika aturan validasi menjamin bahwa NaN dikecualikan. Ini dapat dilakukan dengan menerapkan dengan validasi finite . Misalnya:
# [ nutype (
validate ( finite ) ,
derive ( PartialEq , Eq , PartialOrd , Ord ) ,
) ]
struct Size ( f64 ) ; Untuk jenis lain, dimungkinkan untuk mendefinisikan pembersih khusus dengan with dan validasi khusus dengan predicate :
use nutype :: nutype ;
# [ nutype (
derive ( Debug , PartialEq , AsRef , Deref ) ,
sanitize ( with = | mut guests| { guests . sort ( ) ; guests } ) ,
validate ( predicate = |guests| !guests . is_empty ( ) ) ,
) ]
pub struct GuestList ( Vec < String > ) ;Dimungkinkan juga untuk menggunakan obat generik:
# [ nutype (
sanitize ( with = | mut v| { v . sort ( ) ; v } ) ,
validate ( predicate = |vec| !vec . is_empty ( ) ) ,
derive ( Debug , PartialEq , AsRef , Deref ) ,
) ]
struct SortedNotEmptyVec < T : Ord > ( Vec < T > ) ;
let wise_friends = SortedNotEmptyVec :: try_new ( vec ! [ "Seneca" , "Zeno" , "Plato" ] ) . unwrap ( ) ;
assert_eq ! ( wise_friends . as_ref ( ) , & [ "Plato" , "Seneca" , "Zeno" ] ) ;
assert_eq ! ( wise_friends . len ( ) , 3 ) ;
let numbers = SortedNotEmptyVec :: try_new ( vec ! [ 4 , 2 , 7 , 1 ] ) . unwrap ( ) ;
assert_eq ! ( numbers . as_ref ( ) , & [ 1 , 2 , 4 , 7 ] ) ;
assert_eq ! ( numbers . len ( ) , 4 ) ; Anda dapat mengatur pembersih khusus menggunakan opsi with . Pembersih khusus adalah fungsi atau penutupan yang menerima nilai jenis dalam dengan kepemilikan dan mengembalikan nilai yang disanitasi.
Misalnya, yang ini
# [ nutype ( sanitize ( with = new_to_old ) ) ]
pub struct CityName ( String ) ;
fn new_to_old ( s : String ) -> String {
s . replace ( "New" , "Old" )
}sama dengan yang berikut:
# [ nutype ( sanitize ( with = |s| s . replace ( "New" , "Old" ) ) ) ]
pub struct CityName ( String ) ;Dan bekerja dengan cara yang sama:
let city = CityName :: new ( "New York" ) ;
assert_eq ! ( city . into_inner ( ) , "Old York" ) ; Dengan cara yang sama dimungkinkan untuk mendefinisikan validator khusus, tetapi fungsi validasi menerima referensi dan mengembalikan bool . Anggap saja sebagai predikat.
# [ nutype ( validate ( predicate = is_valid_name ) ) ]
pub struct Name ( String ) ;
fn is_valid_name ( name : & str ) -> bool {
// A fancy way to verify if the first character is uppercase
name . chars ( ) . next ( ) . map ( char :: is_uppercase ) . unwrap_or ( false )
} Untuk menentukan jenis kesalahan Anda sendiri dan mengimplementasikan logika validasi khusus, Anda dapat menggabungkan atribut with dan error :
// Define a custom error type for validation failures.
// Although it's best practice to implement `std::error::Error` for custom error types,
// we are omitting that for simplicity here.
# [ derive ( Debug , PartialEq ) ]
enum NameError {
TooShort ,
TooLong ,
}
// Define a custom validation function for `Name`.
// The function returns `Result<(), NameError>`, where `Ok(())` indicates a valid name,
// and `Err(NameError)` represents a specific validation failure.
fn validate_name ( name : & str ) -> Result < ( ) , NameError > {
if name . len ( ) < 3 {
Err ( NameError :: TooShort )
} else if name . len ( ) > 10 {
Err ( NameError :: TooLong )
} else {
Ok ( ( ) )
}
}
// Define a newtype `Name` with custom validation logic and custom error.
# [ nutype (
validate ( with = validate_name , error = NameError ) ,
derive ( Debug , PartialEq ) ,
) ]
struct Name ( String ) ; Penting untuk memastikan bahwa jenis yang ditentukan dalam atribut error cocok dengan tipe kesalahan yang dikembalikan oleh fungsi validasi.
Default # [ nutype (
derive ( Default ) ,
default = "Anonymous" ,
) ]
pub struct Name ( String ) ;Eq dan Ord pada jenis float Dengan nutype dimungkinkan untuk mendapatkan Eq dan Ord jika ada set validasi finite . Validasi finite memastikan bahwa nilai yang valid tidak termasuk NaN .
# [ nutype (
validate ( finite ) ,
derive ( PartialEq , Eq , PartialOrd , Ord ) ,
) ]
pub struct Weight ( f64 ) ; Ini berkecil hati, tetapi dimungkinkan untuk memotong kendala dengan mengaktifkan fitur peti new_unchecked dan menandai tipe dengan new_unchecked :
# [ nutype (
new_unchecked ,
sanitize ( trim ) ,
validate ( len_char_min = 8 )
) ]
pub struct Name ( String ) ;
// Yes, you're forced to use `unsafe` here, so everyone will point fingers at YOU.
let name = unsafe { Name :: new_unchecked ( " boo " . to_string ( ) ) } ;
// `name` violates the sanitization and validation rules!!!
assert_eq ! ( name . into_inner ( ) , " boo " ) ; arbitrary - Mengaktifkan berasal dari arbitrary::Arbitrary .new_unchecked - memungkinkan generasi fungsi yang tidak aman ::new_unchecked() .regex - memungkinkan untuk menggunakan regex = validasi pada tipe berbasis string. CATATAN: Peti Anda juga harus secara eksplisit memiliki regex dalam dependensinya.serde - Integrasi dengan serde CRATE. Memungkinkan untuk memperoleh Serialize dan Deserialize sifat.schemars08 - memungkinkan untuk memperoleh JsonSchema crait crate schemars. Perhatikan bahwa aturan validasi saat ini tidak dihormati.std - Diaktifkan secara default. Gunakan default-features = false untuk menonaktifkan. Hari ini saya tinggal di Berlin, saya memiliki kemewahan untuk menjalani kehidupan yang aman secara fisik. Tapi saya Ukraina. 25 tahun pertama dalam hidup saya yang saya habiskan di Kharkiv, kota terbesar kedua di Ukraina, 60 km jauhnya dari perbatasan dengan Rusia. Hari ini sekitar sepertiga dari kota asal saya dihancurkan oleh Rusia. Orang tua saya, kerabat saya, dan teman -teman saya harus selamat dari artileri dan serangan udara, tinggal lebih dari sebulan di ruang bawah tanah.
Beberapa dari mereka telah berhasil mengungsi ke UE. Beberapa orang lain mencoba menjalani "kehidupan normal" di Kharkiv, melakukan tugas harian di sana. Dan beberapa berada di garis depan sekarang, mempertaruhkan hidup mereka setiap detik untuk melindungi sisanya.
Saya mendorong Anda untuk menyumbang ke Charity Foundation of Serhiy Prytula. Pilih saja proyek yang Anda suka dan donasi. Ini adalah salah satu yayasan paling terkenal, Anda dapat menonton film dokumenter tentang hal itu. Kontribusi Anda terhadap pasukan militer Ukraina adalah kontribusi untuk ketenangan saya, sehingga saya dapat menghabiskan lebih banyak waktu untuk mengembangkan proyek.
Terima kasih.
MIT © SERHII POTAPOV