Can create a family member
This commit is contained in:
		
							
								
								
									
										320
									
								
								geneit_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										320
									
								
								geneit_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							@@ -271,6 +271,21 @@ dependencies = [
 | 
				
			|||||||
 "alloc-no-stdlib",
 | 
					 "alloc-no-stdlib",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "android-tzdata"
 | 
				
			||||||
 | 
					version = "0.1.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "android_system_properties"
 | 
				
			||||||
 | 
					version = "0.1.5"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "anstream"
 | 
					name = "anstream"
 | 
				
			||||||
version = "0.3.2"
 | 
					version = "0.3.2"
 | 
				
			||||||
@@ -361,9 +376,9 @@ checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "bcrypt"
 | 
					name = "bcrypt"
 | 
				
			||||||
version = "0.14.0"
 | 
					version = "0.15.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9df288bec72232f78c1ec5fe4e8f1d108aa0265476e93097593c803c8c02062a"
 | 
					checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3"
 | 
				
			||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "base64",
 | 
					 "base64",
 | 
				
			||||||
 "blowfish",
 | 
					 "blowfish",
 | 
				
			||||||
@@ -466,6 +481,19 @@ version = "1.0.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
					checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "chrono"
 | 
				
			||||||
 | 
					version = "0.4.26"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "android-tzdata",
 | 
				
			||||||
 | 
					 "iana-time-zone",
 | 
				
			||||||
 | 
					 "num-traits",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "cipher"
 | 
					name = "cipher"
 | 
				
			||||||
version = "0.4.4"
 | 
					version = "0.4.4"
 | 
				
			||||||
@@ -594,6 +622,62 @@ dependencies = [
 | 
				
			|||||||
 "typenum",
 | 
					 "typenum",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "csv"
 | 
				
			||||||
 | 
					version = "1.2.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "csv-core",
 | 
				
			||||||
 | 
					 "itoa",
 | 
				
			||||||
 | 
					 "ryu",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "csv-core"
 | 
				
			||||||
 | 
					version = "0.1.10"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "memchr",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "darling"
 | 
				
			||||||
 | 
					version = "0.20.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "darling_core",
 | 
				
			||||||
 | 
					 "darling_macro",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "darling_core"
 | 
				
			||||||
 | 
					version = "0.20.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "fnv",
 | 
				
			||||||
 | 
					 "ident_case",
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "strsim",
 | 
				
			||||||
 | 
					 "syn 2.0.23",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "darling_macro"
 | 
				
			||||||
 | 
					version = "0.20.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "darling_core",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn 2.0.23",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "derive_more"
 | 
					name = "derive_more"
 | 
				
			||||||
version = "0.99.17"
 | 
					version = "0.99.17"
 | 
				
			||||||
@@ -651,6 +735,27 @@ dependencies = [
 | 
				
			|||||||
 "crypto-common",
 | 
					 "crypto-common",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "dirs-next"
 | 
				
			||||||
 | 
					version = "2.0.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cfg-if",
 | 
				
			||||||
 | 
					 "dirs-sys-next",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "dirs-sys-next"
 | 
				
			||||||
 | 
					version = "0.1.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "libc",
 | 
				
			||||||
 | 
					 "redox_users",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "email-encoding"
 | 
					name = "email-encoding"
 | 
				
			||||||
version = "0.2.0"
 | 
					version = "0.2.0"
 | 
				
			||||||
@@ -667,6 +772,12 @@ version = "0.2.4"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
 | 
					checksum = "e2153bd83ebc09db15bcbdc3e2194d901804952e3dc96967e1cd3b0c5c32d112"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "encode_unicode"
 | 
				
			||||||
 | 
					version = "1.0.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "encoding_rs"
 | 
					name = "encoding_rs"
 | 
				
			||||||
version = "0.8.32"
 | 
					version = "0.8.32"
 | 
				
			||||||
@@ -848,8 +959,10 @@ dependencies = [
 | 
				
			|||||||
 "mailchecker",
 | 
					 "mailchecker",
 | 
				
			||||||
 "rand",
 | 
					 "rand",
 | 
				
			||||||
 "redis",
 | 
					 "redis",
 | 
				
			||||||
 | 
					 "rust_iso3166",
 | 
				
			||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
 "serde_json",
 | 
					 "serde_json",
 | 
				
			||||||
 | 
					 "serde_with",
 | 
				
			||||||
 "thiserror",
 | 
					 "thiserror",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -917,6 +1030,12 @@ version = "0.3.2"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
 | 
					checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hex"
 | 
				
			||||||
 | 
					version = "0.4.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "hostname"
 | 
					name = "hostname"
 | 
				
			||||||
version = "0.3.1"
 | 
					version = "0.3.1"
 | 
				
			||||||
@@ -1005,6 +1124,35 @@ dependencies = [
 | 
				
			|||||||
 "tokio-native-tls",
 | 
					 "tokio-native-tls",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "iana-time-zone"
 | 
				
			||||||
 | 
					version = "0.1.57"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "android_system_properties",
 | 
				
			||||||
 | 
					 "core-foundation-sys",
 | 
				
			||||||
 | 
					 "iana-time-zone-haiku",
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					 "windows",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "iana-time-zone-haiku"
 | 
				
			||||||
 | 
					version = "0.1.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "cc",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "ident_case"
 | 
				
			||||||
 | 
					version = "1.0.1"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "idna"
 | 
					name = "idna"
 | 
				
			||||||
version = "0.3.0"
 | 
					version = "0.3.0"
 | 
				
			||||||
@@ -1033,6 +1181,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "autocfg",
 | 
					 "autocfg",
 | 
				
			||||||
 "hashbrown",
 | 
					 "hashbrown",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
@@ -1289,6 +1438,15 @@ dependencies = [
 | 
				
			|||||||
 "minimal-lexical",
 | 
					 "minimal-lexical",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "num-traits"
 | 
				
			||||||
 | 
					version = "0.2.16"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "autocfg",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "num_cpus"
 | 
					name = "num_cpus"
 | 
				
			||||||
version = "1.16.0"
 | 
					version = "1.16.0"
 | 
				
			||||||
@@ -1376,7 +1534,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
 | 
				
			|||||||
dependencies = [
 | 
					dependencies = [
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
 "redox_syscall",
 | 
					 "redox_syscall 0.3.5",
 | 
				
			||||||
 "smallvec",
 | 
					 "smallvec",
 | 
				
			||||||
 "windows-targets",
 | 
					 "windows-targets",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
@@ -1393,6 +1551,48 @@ version = "2.3.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 | 
					checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "phf"
 | 
				
			||||||
 | 
					version = "0.11.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "phf_macros",
 | 
				
			||||||
 | 
					 "phf_shared",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "phf_generator"
 | 
				
			||||||
 | 
					version = "0.11.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "phf_shared",
 | 
				
			||||||
 | 
					 "rand",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "phf_macros"
 | 
				
			||||||
 | 
					version = "0.11.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "phf_generator",
 | 
				
			||||||
 | 
					 "phf_shared",
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn 2.0.23",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "phf_shared"
 | 
				
			||||||
 | 
					version = "0.11.2"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "siphasher",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "pin-project-lite"
 | 
					name = "pin-project-lite"
 | 
				
			||||||
version = "0.2.10"
 | 
					version = "0.2.10"
 | 
				
			||||||
@@ -1426,6 +1626,20 @@ dependencies = [
 | 
				
			|||||||
 "vcpkg",
 | 
					 "vcpkg",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "prettytable-rs"
 | 
				
			||||||
 | 
					version = "0.10.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "eea25e07510aa6ab6547308ebe3c036016d162b8da920dbb079e3ba8acf3d95a"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "csv",
 | 
				
			||||||
 | 
					 "encode_unicode",
 | 
				
			||||||
 | 
					 "is-terminal",
 | 
				
			||||||
 | 
					 "lazy_static",
 | 
				
			||||||
 | 
					 "term",
 | 
				
			||||||
 | 
					 "unicode-width",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "proc-macro2"
 | 
					name = "proc-macro2"
 | 
				
			||||||
version = "1.0.63"
 | 
					version = "1.0.63"
 | 
				
			||||||
@@ -1494,6 +1708,15 @@ dependencies = [
 | 
				
			|||||||
 "url",
 | 
					 "url",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "redox_syscall"
 | 
				
			||||||
 | 
					version = "0.2.16"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "bitflags 1.3.2",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "redox_syscall"
 | 
					name = "redox_syscall"
 | 
				
			||||||
version = "0.3.5"
 | 
					version = "0.3.5"
 | 
				
			||||||
@@ -1503,6 +1726,17 @@ dependencies = [
 | 
				
			|||||||
 "bitflags 1.3.2",
 | 
					 "bitflags 1.3.2",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "redox_users"
 | 
				
			||||||
 | 
					version = "0.4.3"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "getrandom",
 | 
				
			||||||
 | 
					 "redox_syscall 0.2.16",
 | 
				
			||||||
 | 
					 "thiserror",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "regex"
 | 
					name = "regex"
 | 
				
			||||||
version = "1.8.4"
 | 
					version = "1.8.4"
 | 
				
			||||||
@@ -1557,6 +1791,18 @@ dependencies = [
 | 
				
			|||||||
 "winreg",
 | 
					 "winreg",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rust_iso3166"
 | 
				
			||||||
 | 
					version = "0.1.10"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "6e19f23f46e5d2f3f1e917ecf5cc988e23ba7fc2a2ce3ef09cb17033842d0ef8"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "js-sys",
 | 
				
			||||||
 | 
					 "phf",
 | 
				
			||||||
 | 
					 "prettytable-rs",
 | 
				
			||||||
 | 
					 "wasm-bindgen",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "rustc-demangle"
 | 
					name = "rustc-demangle"
 | 
				
			||||||
version = "0.1.23"
 | 
					version = "0.1.23"
 | 
				
			||||||
@@ -1599,6 +1845,12 @@ dependencies = [
 | 
				
			|||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "rustversion"
 | 
				
			||||||
 | 
					version = "1.0.14"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "ryu"
 | 
					name = "ryu"
 | 
				
			||||||
version = "1.0.14"
 | 
					version = "1.0.14"
 | 
				
			||||||
@@ -1692,6 +1944,34 @@ dependencies = [
 | 
				
			|||||||
 "serde",
 | 
					 "serde",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_with"
 | 
				
			||||||
 | 
					version = "3.1.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "21e47d95bc83ed33b2ecf84f4187ad1ab9685d18ff28db000c99deac8ce180e3"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "base64",
 | 
				
			||||||
 | 
					 "chrono",
 | 
				
			||||||
 | 
					 "hex",
 | 
				
			||||||
 | 
					 "indexmap",
 | 
				
			||||||
 | 
					 "serde",
 | 
				
			||||||
 | 
					 "serde_json",
 | 
				
			||||||
 | 
					 "serde_with_macros",
 | 
				
			||||||
 | 
					 "time",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "serde_with_macros"
 | 
				
			||||||
 | 
					version = "3.1.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "ea3cee93715c2e266b9338b7544da68a9f24e227722ba482bd1c024367c77c65"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "darling",
 | 
				
			||||||
 | 
					 "proc-macro2",
 | 
				
			||||||
 | 
					 "quote",
 | 
				
			||||||
 | 
					 "syn 2.0.23",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "sha1"
 | 
					name = "sha1"
 | 
				
			||||||
version = "0.10.5"
 | 
					version = "0.10.5"
 | 
				
			||||||
@@ -1718,6 +1998,12 @@ dependencies = [
 | 
				
			|||||||
 "libc",
 | 
					 "libc",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "siphasher"
 | 
				
			||||||
 | 
					version = "0.3.10"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "slab"
 | 
					name = "slab"
 | 
				
			||||||
version = "0.4.8"
 | 
					version = "0.4.8"
 | 
				
			||||||
@@ -1786,11 +2072,22 @@ dependencies = [
 | 
				
			|||||||
 "autocfg",
 | 
					 "autocfg",
 | 
				
			||||||
 "cfg-if",
 | 
					 "cfg-if",
 | 
				
			||||||
 "fastrand",
 | 
					 "fastrand",
 | 
				
			||||||
 "redox_syscall",
 | 
					 "redox_syscall 0.3.5",
 | 
				
			||||||
 "rustix 0.37.22",
 | 
					 "rustix 0.37.22",
 | 
				
			||||||
 "windows-sys",
 | 
					 "windows-sys",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "term"
 | 
				
			||||||
 | 
					version = "0.7.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "dirs-next",
 | 
				
			||||||
 | 
					 "rustversion",
 | 
				
			||||||
 | 
					 "winapi",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "termcolor"
 | 
					name = "termcolor"
 | 
				
			||||||
version = "1.2.0"
 | 
					version = "1.2.0"
 | 
				
			||||||
@@ -1964,6 +2261,12 @@ dependencies = [
 | 
				
			|||||||
 "tinyvec",
 | 
					 "tinyvec",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "unicode-width"
 | 
				
			||||||
 | 
					version = "0.1.10"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "url"
 | 
					name = "url"
 | 
				
			||||||
version = "2.4.0"
 | 
					version = "2.4.0"
 | 
				
			||||||
@@ -2121,6 +2424,15 @@ version = "0.4.0"
 | 
				
			|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
					checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "windows"
 | 
				
			||||||
 | 
					version = "0.48.0"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "windows-targets",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "windows-sys"
 | 
					name = "windows-sys"
 | 
				
			||||||
version = "0.48.0"
 | 
					version = "0.48.0"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,8 @@ mailchecker = "5.0.9"
 | 
				
			|||||||
redis = "0.23.0"
 | 
					redis = "0.23.0"
 | 
				
			||||||
lettre = "0.10.4"
 | 
					lettre = "0.10.4"
 | 
				
			||||||
rand = "0.8.5"
 | 
					rand = "0.8.5"
 | 
				
			||||||
bcrypt = "0.14.0"
 | 
					bcrypt = "0.15.0"
 | 
				
			||||||
light-openid = "1.0.1"
 | 
					light-openid = "1.0.1"
 | 
				
			||||||
thiserror = "1.0.40"
 | 
					thiserror = "1.0.40"
 | 
				
			||||||
 | 
					serde_with = "3.1.0"
 | 
				
			||||||
 | 
					rust_iso3166 = "0.1.10"
 | 
				
			||||||
							
								
								
									
										253
									
								
								geneit_backend/assets/iso-3166_country_french.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										253
									
								
								geneit_backend/assets/iso-3166_country_french.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,253 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"AD" : "Andorre",
 | 
				
			||||||
 | 
						"AE" : "Émirats Arabes Unis",
 | 
				
			||||||
 | 
						"AF" : "Afghanistan",
 | 
				
			||||||
 | 
						"AG" : "Antigua-Et-Barbuda",
 | 
				
			||||||
 | 
						"AI" : "Anguilla",
 | 
				
			||||||
 | 
						"AL" : "Albanie",
 | 
				
			||||||
 | 
						"AM" : "Arménie",
 | 
				
			||||||
 | 
						"AO" : "Angola",
 | 
				
			||||||
 | 
						"AP" : "Région Asie/Pacifique",
 | 
				
			||||||
 | 
						"AQ" : "Antarctique",
 | 
				
			||||||
 | 
						"AR" : "Argentine",
 | 
				
			||||||
 | 
						"AS" : "Samoa Américaines",
 | 
				
			||||||
 | 
						"AT" : "Autriche",
 | 
				
			||||||
 | 
						"AU" : "Australie",
 | 
				
			||||||
 | 
						"AW" : "Aruba",
 | 
				
			||||||
 | 
						"AX" : "Îles Åland",
 | 
				
			||||||
 | 
						"AZ" : "Azerbaïdjan",
 | 
				
			||||||
 | 
						"BA" : "Bosnie-Herzégovine",
 | 
				
			||||||
 | 
						"BB" : "Barbad",
 | 
				
			||||||
 | 
						"BD" : "Bangladesh",
 | 
				
			||||||
 | 
						"BE" : "Belgique",
 | 
				
			||||||
 | 
						"BF" : "Burkina Faso",
 | 
				
			||||||
 | 
						"BG" : "Bulgarie",
 | 
				
			||||||
 | 
						"BH" : "Bahreïn",
 | 
				
			||||||
 | 
						"BI" : "Burundi",
 | 
				
			||||||
 | 
						"BJ" : "Bénin",
 | 
				
			||||||
 | 
						"BL" : "Saint-Barthélemy",
 | 
				
			||||||
 | 
						"BM" : "Bermudes",
 | 
				
			||||||
 | 
						"BN" : "Brunei Darussalam",
 | 
				
			||||||
 | 
						"BO" : "État Plurinational De Bolivie",
 | 
				
			||||||
 | 
						"BQ" : "Bonaire, Saint-Eustache Et Saba",
 | 
				
			||||||
 | 
						"BR" : "Brésil",
 | 
				
			||||||
 | 
						"BS" : "Bahamas",
 | 
				
			||||||
 | 
						"BT" : "Bhoutan",
 | 
				
			||||||
 | 
						"BV" : "Île Bouvet",
 | 
				
			||||||
 | 
						"BW" : "Botswana",
 | 
				
			||||||
 | 
						"BY" : "Biélorussie",
 | 
				
			||||||
 | 
						"BZ" : "Belize",
 | 
				
			||||||
 | 
						"CA" : "Canada",
 | 
				
			||||||
 | 
						"CC" : "Îles Cocos",
 | 
				
			||||||
 | 
						"CD" : "République Démocratique Du Congo",
 | 
				
			||||||
 | 
						"CF" : "République Centrafricaine",
 | 
				
			||||||
 | 
						"CG" : "Congo",
 | 
				
			||||||
 | 
						"CH" : "Suisse",
 | 
				
			||||||
 | 
						"CI" : "Côte D'Ivoire",
 | 
				
			||||||
 | 
						"CK" : "Îles Cook",
 | 
				
			||||||
 | 
						"CL" : "Chili",
 | 
				
			||||||
 | 
						"CM" : "Cameroun",
 | 
				
			||||||
 | 
						"CN" : "Chine",
 | 
				
			||||||
 | 
						"CO" : "Colombie",
 | 
				
			||||||
 | 
						"CR" : "Costa Rica",
 | 
				
			||||||
 | 
						"CU" : "Cuba",
 | 
				
			||||||
 | 
						"CV" : "Cap-Vert",
 | 
				
			||||||
 | 
						"CW" : "Curaçao",
 | 
				
			||||||
 | 
						"CX" : "Île Christmas",
 | 
				
			||||||
 | 
						"CY" : "Chypre",
 | 
				
			||||||
 | 
						"CZ" : "République Tchèque",
 | 
				
			||||||
 | 
						"DE" : "Allemagne",
 | 
				
			||||||
 | 
						"DJ" : "Djibouti",
 | 
				
			||||||
 | 
						"DK" : "Denmark",
 | 
				
			||||||
 | 
						"DM" : "Dominique",
 | 
				
			||||||
 | 
						"DO" : "République Dominicaine",
 | 
				
			||||||
 | 
						"DZ" : "Algérie",
 | 
				
			||||||
 | 
						"EC" : "Équateur",
 | 
				
			||||||
 | 
						"EE" : "Estonie",
 | 
				
			||||||
 | 
						"EG" : "Égypte",
 | 
				
			||||||
 | 
						"EH" : "Sahara Occidental",
 | 
				
			||||||
 | 
						"ER" : "Érythrée",
 | 
				
			||||||
 | 
						"ES" : "Espagne",
 | 
				
			||||||
 | 
						"ET" : "Éthiopie",
 | 
				
			||||||
 | 
						"EU" : "Europe",
 | 
				
			||||||
 | 
						"FI" : "Finlande",
 | 
				
			||||||
 | 
						"FJ" : "Fidji",
 | 
				
			||||||
 | 
						"FK" : "Îles Malouines",
 | 
				
			||||||
 | 
						"FM" : "États Fédérés De Micronésie",
 | 
				
			||||||
 | 
						"FO" : "Îles Féroé",
 | 
				
			||||||
 | 
						"FR" : "France",
 | 
				
			||||||
 | 
						"GA" : "Gabon",
 | 
				
			||||||
 | 
						"GB" : "Royaume-Uni",
 | 
				
			||||||
 | 
						"GD" : "Grenade",
 | 
				
			||||||
 | 
						"GE" : "Géorgie",
 | 
				
			||||||
 | 
						"GF" : "Guyane",
 | 
				
			||||||
 | 
						"GG" : "Guernesey",
 | 
				
			||||||
 | 
						"GH" : "Ghana",
 | 
				
			||||||
 | 
						"GI" : "Gibraltar",
 | 
				
			||||||
 | 
						"GL" : "Groenland",
 | 
				
			||||||
 | 
						"GM" : "Gambie",
 | 
				
			||||||
 | 
						"GN" : "Guinée",
 | 
				
			||||||
 | 
						"GP" : "Guadeloupe",
 | 
				
			||||||
 | 
						"GQ" : "Guinée Équatoriale",
 | 
				
			||||||
 | 
						"GR" : "Grèce",
 | 
				
			||||||
 | 
						"GS" : "Géorgie Du Sud-Et-Les Îles Sandwich Du Sud",
 | 
				
			||||||
 | 
						"GT" : "Guatemala",
 | 
				
			||||||
 | 
						"GU" : "Guam",
 | 
				
			||||||
 | 
						"GW" : "Guinée-Bissau",
 | 
				
			||||||
 | 
						"GY" : "Guyana",
 | 
				
			||||||
 | 
						"HK" : "Hong Kong",
 | 
				
			||||||
 | 
						"HM" : "Îles Heard-Et-MacDonald",
 | 
				
			||||||
 | 
						"HN" : "Honduras",
 | 
				
			||||||
 | 
						"HR" : "Croatie",
 | 
				
			||||||
 | 
						"HT" : "Haïti",
 | 
				
			||||||
 | 
						"HU" : "Hongrie",
 | 
				
			||||||
 | 
						"ID" : "Indonésie",
 | 
				
			||||||
 | 
						"IE" : "Irlande",
 | 
				
			||||||
 | 
						"IL" : "Israël",
 | 
				
			||||||
 | 
						"IM" : "Île De Man",
 | 
				
			||||||
 | 
						"IN" : "Inde",
 | 
				
			||||||
 | 
						"IO" : "Territoire Britannique De L'océan Indien",
 | 
				
			||||||
 | 
						"IQ" : "Irak",
 | 
				
			||||||
 | 
						"IR" : "République Islamique D'Iran",
 | 
				
			||||||
 | 
						"IS" : "Islande",
 | 
				
			||||||
 | 
						"IT" : "Italie",
 | 
				
			||||||
 | 
						"JE" : "Jersey",
 | 
				
			||||||
 | 
						"JM" : "Jamaïque",
 | 
				
			||||||
 | 
						"JO" : "Jordanie",
 | 
				
			||||||
 | 
						"JP" : "Japon",
 | 
				
			||||||
 | 
						"KE" : "Kenya",
 | 
				
			||||||
 | 
						"KG" : "Kirghizistan",
 | 
				
			||||||
 | 
						"KH" : "Cambodge",
 | 
				
			||||||
 | 
						"KI" : "Kiribati",
 | 
				
			||||||
 | 
						"KM" : "Comores",
 | 
				
			||||||
 | 
						"KN" : "Saint-Christophe-et-Niévès",
 | 
				
			||||||
 | 
						"KP" : "République Populaire Démocratique De Corée",
 | 
				
			||||||
 | 
						"KR" : "République De Corée",
 | 
				
			||||||
 | 
						"KW" : "Koweït",
 | 
				
			||||||
 | 
						"KY" : "Îles Caïmans",
 | 
				
			||||||
 | 
						"KZ" : "Kazakhstan",
 | 
				
			||||||
 | 
						"LA" : "République Démocratique Populaire Lao",
 | 
				
			||||||
 | 
						"LB" : "Liban",
 | 
				
			||||||
 | 
						"LC" : "Sainte-Lucie",
 | 
				
			||||||
 | 
						"LI" : "Liechtenstein",
 | 
				
			||||||
 | 
						"LK" : "Sri Lanka",
 | 
				
			||||||
 | 
						"LR" : "Liberia",
 | 
				
			||||||
 | 
						"LS" : "Lesotho",
 | 
				
			||||||
 | 
						"LT" : "Lituanie",
 | 
				
			||||||
 | 
						"LU" : "Luxembourg",
 | 
				
			||||||
 | 
						"LV" : "Lettonie",
 | 
				
			||||||
 | 
						"LY" : "Libye",
 | 
				
			||||||
 | 
						"MA" : "Maroc",
 | 
				
			||||||
 | 
						"MC" : "Monaco",
 | 
				
			||||||
 | 
						"MD" : "République De Moldavie",
 | 
				
			||||||
 | 
						"ME" : "Monténégro",
 | 
				
			||||||
 | 
						"MF" : "Saint-Martin (Partie Française)",
 | 
				
			||||||
 | 
						"MG" : "Madagascar",
 | 
				
			||||||
 | 
						"MH" : "Îles Marshall",
 | 
				
			||||||
 | 
						"MK" : "Macédoine",
 | 
				
			||||||
 | 
						"ML" : "Mali",
 | 
				
			||||||
 | 
						"MM" : "Birmanie",
 | 
				
			||||||
 | 
						"MN" : "Mongolie",
 | 
				
			||||||
 | 
						"MO" : "Macao",
 | 
				
			||||||
 | 
						"MP" : "Îles Mariannes Du Nord",
 | 
				
			||||||
 | 
						"MQ" : "Martinique",
 | 
				
			||||||
 | 
						"MR" : "Mauritanie",
 | 
				
			||||||
 | 
						"MS" : "Montserrat",
 | 
				
			||||||
 | 
						"MT" : "Malte",
 | 
				
			||||||
 | 
						"MU" : "Maurice",
 | 
				
			||||||
 | 
						"MV" : "Maldives",
 | 
				
			||||||
 | 
						"MW" : "Malawi",
 | 
				
			||||||
 | 
						"MX" : "Mexique",
 | 
				
			||||||
 | 
						"MY" : "Malaisie",
 | 
				
			||||||
 | 
						"MZ" : "Mozambique",
 | 
				
			||||||
 | 
						"NA" : "Namibie",
 | 
				
			||||||
 | 
						"NC" : "Nouvelle-Calédonie",
 | 
				
			||||||
 | 
						"NE" : "Niger",
 | 
				
			||||||
 | 
						"NF" : "Île Norfolk",
 | 
				
			||||||
 | 
						"NG" : "Nigéria",
 | 
				
			||||||
 | 
						"NI" : "Nicaragua",
 | 
				
			||||||
 | 
						"NL" : "Pays-Bas",
 | 
				
			||||||
 | 
						"NO" : "Norvège",
 | 
				
			||||||
 | 
						"NP" : "Népal",
 | 
				
			||||||
 | 
						"NR" : "Nauru",
 | 
				
			||||||
 | 
						"NU" : "Niue",
 | 
				
			||||||
 | 
						"NZ" : "Nouvelle-Zélande",
 | 
				
			||||||
 | 
						"OM" : "Oman",
 | 
				
			||||||
 | 
						"PA" : "Panama",
 | 
				
			||||||
 | 
						"PE" : "Pérou",
 | 
				
			||||||
 | 
						"PF" : "Polynésie Française",
 | 
				
			||||||
 | 
						"PG" : "Papouasie-Nouvelle-Guinée",
 | 
				
			||||||
 | 
						"PH" : "Philippines",
 | 
				
			||||||
 | 
						"PK" : "Pakistan",
 | 
				
			||||||
 | 
						"PL" : "Pologne",
 | 
				
			||||||
 | 
						"PM" : "Saint-Pierre-Et-Miquelon",
 | 
				
			||||||
 | 
						"PN" : "Pitcairn",
 | 
				
			||||||
 | 
						"PR" : "Porto Rico",
 | 
				
			||||||
 | 
						"PS" : "Territoires Palestiniens Occupés",
 | 
				
			||||||
 | 
						"PT" : "Portugal",
 | 
				
			||||||
 | 
						"PW" : "Palaos",
 | 
				
			||||||
 | 
						"PY" : "Paraguay",
 | 
				
			||||||
 | 
						"QA" : "Qatar",
 | 
				
			||||||
 | 
						"RE" : "Réunion",
 | 
				
			||||||
 | 
						"RO" : "Roumanie",
 | 
				
			||||||
 | 
						"RS" : "Serbie",
 | 
				
			||||||
 | 
						"RU" : "Fédération De Russie",
 | 
				
			||||||
 | 
						"RW" : "Rwanda",
 | 
				
			||||||
 | 
						"SA" : "Arabie Saoudite",
 | 
				
			||||||
 | 
						"SB" : "Îles Salomon",
 | 
				
			||||||
 | 
						"SC" : "Seychelles",
 | 
				
			||||||
 | 
						"SD" : "Soudan",
 | 
				
			||||||
 | 
						"SE" : "Suède",
 | 
				
			||||||
 | 
						"SG" : "Singapour",
 | 
				
			||||||
 | 
						"SH" : "Sainte-Hélène",
 | 
				
			||||||
 | 
						"SI" : "Slovénie",
 | 
				
			||||||
 | 
						"SJ" : "Svalbard Et Jan Mayen",
 | 
				
			||||||
 | 
						"SK" : "Slovaquie",
 | 
				
			||||||
 | 
						"SL" : "Sierra Leone",
 | 
				
			||||||
 | 
						"SM" : "Saint-Marin",
 | 
				
			||||||
 | 
						"SN" : "Sénégal",
 | 
				
			||||||
 | 
						"SO" : "Somalie",
 | 
				
			||||||
 | 
						"SR" : "Suriname",
 | 
				
			||||||
 | 
						"SS" : "Soudan Du Sud",
 | 
				
			||||||
 | 
						"ST" : "Sao Tomé-Et-Principe",
 | 
				
			||||||
 | 
						"SV" : "République Du Salvador",
 | 
				
			||||||
 | 
						"SX" : "Saint-Martin (Partie Néerlandaise)",
 | 
				
			||||||
 | 
						"SY" : "République Arabe Syrienne",
 | 
				
			||||||
 | 
						"SZ" : "Swaziland",
 | 
				
			||||||
 | 
						"TC" : "Îles Turks-Et-Caïcos",
 | 
				
			||||||
 | 
						"TD" : "Tchad",
 | 
				
			||||||
 | 
						"TF" : "Terres Australes Françaises",
 | 
				
			||||||
 | 
						"TG" : "Togo",
 | 
				
			||||||
 | 
						"TH" : "Thaïlande",
 | 
				
			||||||
 | 
						"TJ" : "Tadjikistan",
 | 
				
			||||||
 | 
						"TK" : "Tokelau",
 | 
				
			||||||
 | 
						"TL" : "Timor-Leste",
 | 
				
			||||||
 | 
						"TM" : "Turkménistan",
 | 
				
			||||||
 | 
						"TN" : "Tunisie",
 | 
				
			||||||
 | 
						"TO" : "Tonga",
 | 
				
			||||||
 | 
						"TR" : "Turquie",
 | 
				
			||||||
 | 
						"TT" : "Trinité-Et-Tobago",
 | 
				
			||||||
 | 
						"TV" : "Tuvalu",
 | 
				
			||||||
 | 
						"TW" : "Taïwan",
 | 
				
			||||||
 | 
						"TZ" : "République-Unie De Tanzanie",
 | 
				
			||||||
 | 
						"UA" : "Ukraine",
 | 
				
			||||||
 | 
						"UG" : "Ouganda",
 | 
				
			||||||
 | 
						"UM" : "Îles Mineures Éloignées Des États-Unis",
 | 
				
			||||||
 | 
						"US" : "États-Unis",
 | 
				
			||||||
 | 
						"UY" : "Uruguay",
 | 
				
			||||||
 | 
						"UZ" : "Ouzbékistan",
 | 
				
			||||||
 | 
						"VA" : "Saint-Siège (État De La Cité Du Vatican)",
 | 
				
			||||||
 | 
						"VC" : "Saint-Vincent-Et-Les Grenadines",
 | 
				
			||||||
 | 
						"VE" : "Venezuela",
 | 
				
			||||||
 | 
						"VG" : "Îles Vierges Britanniques",
 | 
				
			||||||
 | 
						"VI" : "Îles Vierges Des États-Unis",
 | 
				
			||||||
 | 
						"VN" : "Viet Nam",
 | 
				
			||||||
 | 
						"VU" : "Vanuatu",
 | 
				
			||||||
 | 
						"WF" : "Wallis Et Futuna",
 | 
				
			||||||
 | 
						"WS" : "Samoa",
 | 
				
			||||||
 | 
						"YE" : "Yémen",
 | 
				
			||||||
 | 
						"YT" : "Mayotte",
 | 
				
			||||||
 | 
						"ZA" : "Afrique Du Sud",
 | 
				
			||||||
 | 
						"ZM" : "Zambie",
 | 
				
			||||||
 | 
						"ZW" : "Zimbabwe"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -42,8 +42,8 @@ CREATE TABLE members (
 | 
				
			|||||||
    address VARCHAR (155) NULL,
 | 
					    address VARCHAR (155) NULL,
 | 
				
			||||||
    city VARCHAR(150) NULL,
 | 
					    city VARCHAR(150) NULL,
 | 
				
			||||||
    postal_code VARCHAR(12) NULL,
 | 
					    postal_code VARCHAR(12) NULL,
 | 
				
			||||||
    country VARCHAR(30) NULL,
 | 
					    country VARCHAR(2) NULL,
 | 
				
			||||||
    sex VARCHAR(1) NOT NULL,
 | 
					    sex VARCHAR(1) NULL,
 | 
				
			||||||
    time_create BIGINT NOT NULL,
 | 
					    time_create BIGINT NOT NULL,
 | 
				
			||||||
    time_update BIGINT NOT NULL,
 | 
					    time_update BIGINT NOT NULL,
 | 
				
			||||||
    mother integer NULL REFERENCES members,
 | 
					    mother integer NULL REFERENCES members,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
use std::time::Duration;
 | 
					use std::time::Duration;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
 | 
					#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
pub struct SizeConstraint {
 | 
					pub struct SizeConstraint {
 | 
				
			||||||
    min: usize,
 | 
					    min: usize,
 | 
				
			||||||
    max: usize,
 | 
					    max: usize,
 | 
				
			||||||
@@ -17,6 +17,23 @@ impl SizeConstraint {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct NumberValueConstraint {
 | 
				
			||||||
 | 
					    min: i64,
 | 
				
			||||||
 | 
					    max: i64,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl NumberValueConstraint {
 | 
				
			||||||
 | 
					    pub fn new(min: i64, max: i64) -> Self {
 | 
				
			||||||
 | 
					        Self { min, max }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn validate(&self, val: impl Into<i64>) -> bool {
 | 
				
			||||||
 | 
					        let val = val.into();
 | 
				
			||||||
 | 
					        val >= self.min && val <= self.max
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug, Clone, serde::Serialize)]
 | 
					#[derive(Debug, Clone, serde::Serialize)]
 | 
				
			||||||
pub struct StaticConstraints {
 | 
					pub struct StaticConstraints {
 | 
				
			||||||
    pub mail_len: SizeConstraint,
 | 
					    pub mail_len: SizeConstraint,
 | 
				
			||||||
@@ -24,6 +41,22 @@ pub struct StaticConstraints {
 | 
				
			|||||||
    pub password_len: SizeConstraint,
 | 
					    pub password_len: SizeConstraint,
 | 
				
			||||||
    pub family_name_len: SizeConstraint,
 | 
					    pub family_name_len: SizeConstraint,
 | 
				
			||||||
    pub invitation_code_len: SizeConstraint,
 | 
					    pub invitation_code_len: SizeConstraint,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub member_first_name: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_last_name: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_birth_last_name: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_email: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_phone: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_address: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_city: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_postal_code: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_country: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_sex: SizeConstraint,
 | 
				
			||||||
 | 
					    pub member_note: SizeConstraint,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub date_year: NumberValueConstraint,
 | 
				
			||||||
 | 
					    pub date_month: NumberValueConstraint,
 | 
				
			||||||
 | 
					    pub date_day: NumberValueConstraint,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for StaticConstraints {
 | 
					impl Default for StaticConstraints {
 | 
				
			||||||
@@ -37,6 +70,20 @@ impl Default for StaticConstraints {
 | 
				
			|||||||
                FAMILY_INVITATION_CODE_LEN,
 | 
					                FAMILY_INVITATION_CODE_LEN,
 | 
				
			||||||
                FAMILY_INVITATION_CODE_LEN,
 | 
					                FAMILY_INVITATION_CODE_LEN,
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
 | 
					            member_first_name: SizeConstraint::new(0, 30),
 | 
				
			||||||
 | 
					            member_last_name: SizeConstraint::new(0, 30),
 | 
				
			||||||
 | 
					            member_birth_last_name: SizeConstraint::new(0, 30),
 | 
				
			||||||
 | 
					            member_email: SizeConstraint::new(0, 255),
 | 
				
			||||||
 | 
					            member_phone: SizeConstraint::new(0, 30),
 | 
				
			||||||
 | 
					            member_address: SizeConstraint::new(0, 155),
 | 
				
			||||||
 | 
					            member_city: SizeConstraint::new(0, 150),
 | 
				
			||||||
 | 
					            member_postal_code: SizeConstraint::new(0, 12),
 | 
				
			||||||
 | 
					            member_country: SizeConstraint::new(0, 2),
 | 
				
			||||||
 | 
					            member_sex: SizeConstraint::new(0, 1),
 | 
				
			||||||
 | 
					            member_note: SizeConstraint::new(0, 35000),
 | 
				
			||||||
 | 
					            date_year: NumberValueConstraint::new(1, 2050),
 | 
				
			||||||
 | 
					            date_month: NumberValueConstraint::new(1, 12),
 | 
				
			||||||
 | 
					            date_day: NumberValueConstraint::new(1, 31),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										242
									
								
								geneit_backend/src/controllers/members_controller.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								geneit_backend/src/controllers/members_controller.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,242 @@
 | 
				
			|||||||
 | 
					use crate::constants::{SizeConstraint, StaticConstraints};
 | 
				
			||||||
 | 
					use crate::controllers::HttpResult;
 | 
				
			||||||
 | 
					use crate::extractors::family_extractor::FamilyInPath;
 | 
				
			||||||
 | 
					use crate::models::{Member, MemberID, Sex};
 | 
				
			||||||
 | 
					use crate::services::members_service;
 | 
				
			||||||
 | 
					use crate::utils::countries_utils;
 | 
				
			||||||
 | 
					use actix_web::{web, HttpResponse};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					serde_with::with_prefix!(prefix_birth "birth_");
 | 
				
			||||||
 | 
					serde_with::with_prefix!(prefix_death "death_");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct RequestDate {
 | 
				
			||||||
 | 
					    pub year: Option<i16>,
 | 
				
			||||||
 | 
					    pub month: Option<i16>,
 | 
				
			||||||
 | 
					    pub day: Option<i16>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl RequestDate {
 | 
				
			||||||
 | 
					    pub fn check(&self) -> bool {
 | 
				
			||||||
 | 
					        let c = StaticConstraints::default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.year.map(|y| c.date_year.validate(y)).unwrap_or(true)
 | 
				
			||||||
 | 
					            && self.month.map(|y| c.date_month.validate(y)).unwrap_or(true)
 | 
				
			||||||
 | 
					            && self.day.map(|y| c.date_day.validate(y)).unwrap_or(true)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct MemberRequest {
 | 
				
			||||||
 | 
					    first_name: Option<String>,
 | 
				
			||||||
 | 
					    last_name: Option<String>,
 | 
				
			||||||
 | 
					    birth_last_name: Option<String>,
 | 
				
			||||||
 | 
					    email: Option<String>,
 | 
				
			||||||
 | 
					    phone: Option<String>,
 | 
				
			||||||
 | 
					    address: Option<String>,
 | 
				
			||||||
 | 
					    city: Option<String>,
 | 
				
			||||||
 | 
					    postal_code: Option<String>,
 | 
				
			||||||
 | 
					    country: Option<String>,
 | 
				
			||||||
 | 
					    sex: Option<Sex>,
 | 
				
			||||||
 | 
					    mother: Option<MemberID>,
 | 
				
			||||||
 | 
					    father: Option<MemberID>,
 | 
				
			||||||
 | 
					    #[serde(flatten, with = "prefix_birth")]
 | 
				
			||||||
 | 
					    birth: Option<RequestDate>,
 | 
				
			||||||
 | 
					    #[serde(flatten, with = "prefix_death")]
 | 
				
			||||||
 | 
					    death: Option<RequestDate>,
 | 
				
			||||||
 | 
					    note: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(thiserror::Error, Debug)]
 | 
				
			||||||
 | 
					enum MemberControllerErr {
 | 
				
			||||||
 | 
					    #[error("Malformed first name!")]
 | 
				
			||||||
 | 
					    MalformedFirstname,
 | 
				
			||||||
 | 
					    #[error("Malformed last name!")]
 | 
				
			||||||
 | 
					    MalformedLastname,
 | 
				
			||||||
 | 
					    #[error("Malformed birth last name!")]
 | 
				
			||||||
 | 
					    MalformedBirthLastname,
 | 
				
			||||||
 | 
					    #[error("Malformed email address!")]
 | 
				
			||||||
 | 
					    MalformedEmailAddress,
 | 
				
			||||||
 | 
					    #[error("Invalid email address!")]
 | 
				
			||||||
 | 
					    InvalidEmailAddress,
 | 
				
			||||||
 | 
					    #[error("Malformed phone number!")]
 | 
				
			||||||
 | 
					    MalformedPhoneNumber,
 | 
				
			||||||
 | 
					    #[error("Malformed address!")]
 | 
				
			||||||
 | 
					    MalformedAddress,
 | 
				
			||||||
 | 
					    #[error("Malformed city!")]
 | 
				
			||||||
 | 
					    MalformedCity,
 | 
				
			||||||
 | 
					    #[error("Malformed postal code!")]
 | 
				
			||||||
 | 
					    MalformedPostalCode,
 | 
				
			||||||
 | 
					    #[error("Malformed country!")]
 | 
				
			||||||
 | 
					    MalformedCountry,
 | 
				
			||||||
 | 
					    #[error("Invalid country code!")]
 | 
				
			||||||
 | 
					    InvalidCountryCode,
 | 
				
			||||||
 | 
					    #[error("Malformed date of birth!")]
 | 
				
			||||||
 | 
					    MalformedDateOfBirth,
 | 
				
			||||||
 | 
					    #[error("Malformed date of death!")]
 | 
				
			||||||
 | 
					    MalformedDateOfDeath,
 | 
				
			||||||
 | 
					    #[error("Malformed note!")]
 | 
				
			||||||
 | 
					    MalformedNote,
 | 
				
			||||||
 | 
					    #[error("Mother does not exists!")]
 | 
				
			||||||
 | 
					    MotherNotExisting,
 | 
				
			||||||
 | 
					    #[error("Father does not exists!")]
 | 
				
			||||||
 | 
					    FatherNotExisting,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn check_opt_str_val(
 | 
				
			||||||
 | 
					    val: &Option<String>,
 | 
				
			||||||
 | 
					    c: SizeConstraint,
 | 
				
			||||||
 | 
					    err: MemberControllerErr,
 | 
				
			||||||
 | 
					) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    if let Some(v) = val {
 | 
				
			||||||
 | 
					        if !c.validate(v) {
 | 
				
			||||||
 | 
					            return Err(err.into());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl MemberRequest {
 | 
				
			||||||
 | 
					    pub async fn to_member(self, member: &mut Member) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					        let c = StaticConstraints::default();
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.first_name,
 | 
				
			||||||
 | 
					            c.member_first_name,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedFirstname,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.last_name,
 | 
				
			||||||
 | 
					            c.member_last_name,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedLastname,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.birth_last_name,
 | 
				
			||||||
 | 
					            c.member_birth_last_name,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedBirthLastname,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.email,
 | 
				
			||||||
 | 
					            c.member_email,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedEmailAddress,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(mail) = &self.email {
 | 
				
			||||||
 | 
					            if !mailchecker::is_valid(mail) {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::InvalidEmailAddress.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.phone,
 | 
				
			||||||
 | 
					            c.member_phone,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedPhoneNumber,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.address,
 | 
				
			||||||
 | 
					            c.member_address,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedAddress,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.city,
 | 
				
			||||||
 | 
					            c.member_city,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedCity,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.postal_code,
 | 
				
			||||||
 | 
					            c.member_postal_code,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedPostalCode,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.country,
 | 
				
			||||||
 | 
					            c.member_country,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedCountry,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(c) = &self.country {
 | 
				
			||||||
 | 
					            if !countries_utils::is_code_valid(c) {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::InvalidCountryCode.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(d) = &self.birth {
 | 
				
			||||||
 | 
					            if !d.check() {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::MalformedDateOfBirth.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(d) = &self.death {
 | 
				
			||||||
 | 
					            if !d.check() {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::MalformedDateOfDeath.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        check_opt_str_val(
 | 
				
			||||||
 | 
					            &self.note,
 | 
				
			||||||
 | 
					            c.member_note,
 | 
				
			||||||
 | 
					            MemberControllerErr::MalformedNote,
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(mother) = self.mother {
 | 
				
			||||||
 | 
					            if !members_service::exists(member.family_id(), mother).await? {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::MotherNotExisting.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if let Some(father) = self.father {
 | 
				
			||||||
 | 
					            if !members_service::exists(member.family_id(), father).await? {
 | 
				
			||||||
 | 
					                return Err(MemberControllerErr::FatherNotExisting.into());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        member.first_name = self.first_name;
 | 
				
			||||||
 | 
					        member.last_name = self.last_name;
 | 
				
			||||||
 | 
					        member.birth_last_name = self.birth_last_name;
 | 
				
			||||||
 | 
					        member.email = self.email;
 | 
				
			||||||
 | 
					        member.phone = self.phone;
 | 
				
			||||||
 | 
					        member.address = self.address;
 | 
				
			||||||
 | 
					        member.city = self.city;
 | 
				
			||||||
 | 
					        member.postal_code = self.postal_code;
 | 
				
			||||||
 | 
					        member.country = self.country;
 | 
				
			||||||
 | 
					        member.set_sex(self.sex);
 | 
				
			||||||
 | 
					        member.set_mother(self.mother);
 | 
				
			||||||
 | 
					        member.set_father(self.father);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        member.birth_year = self.birth.as_ref().map(|m| m.year).unwrap_or_default();
 | 
				
			||||||
 | 
					        member.birth_month = self.birth.as_ref().map(|m| m.month).unwrap_or_default();
 | 
				
			||||||
 | 
					        member.birth_day = self.birth.as_ref().map(|m| m.day).unwrap_or_default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        member.death_year = self.death.as_ref().map(|m| m.year).unwrap_or_default();
 | 
				
			||||||
 | 
					        member.death_month = self.death.as_ref().map(|m| m.month).unwrap_or_default();
 | 
				
			||||||
 | 
					        member.death_day = self.death.as_ref().map(|m| m.day).unwrap_or_default();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        member.note = self.note;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Create a new family member
 | 
				
			||||||
 | 
					pub async fn create(f: FamilyInPath, req: web::Json<MemberRequest>) -> HttpResult {
 | 
				
			||||||
 | 
					    let mut member = members_service::create(f.family_id()).await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(e) = req.0.to_member(&mut member).await {
 | 
				
			||||||
 | 
					        log::error!("Failed to apply member information! {e}");
 | 
				
			||||||
 | 
					        members_service::delete(&member).await?;
 | 
				
			||||||
 | 
					        return Ok(HttpResponse::BadRequest().body(e.to_string()));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if let Err(e) = members_service::update(&mut member).await {
 | 
				
			||||||
 | 
					        log::error!("Failed to update member information! {e}");
 | 
				
			||||||
 | 
					        members_service::delete(&member).await?;
 | 
				
			||||||
 | 
					        return Ok(HttpResponse::InternalServerError().finish());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(HttpResponse::Ok().json(member))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,6 +6,7 @@ use std::fmt::{Debug, Display, Formatter};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
pub mod auth_controller;
 | 
					pub mod auth_controller;
 | 
				
			||||||
pub mod families_controller;
 | 
					pub mod families_controller;
 | 
				
			||||||
 | 
					pub mod members_controller;
 | 
				
			||||||
pub mod server_controller;
 | 
					pub mod server_controller;
 | 
				
			||||||
pub mod users_controller;
 | 
					pub mod users_controller;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,7 @@
 | 
				
			|||||||
use crate::app_config::{AppConfig, OIDCProvider};
 | 
					use crate::app_config::{AppConfig, OIDCProvider};
 | 
				
			||||||
use crate::constants::StaticConstraints;
 | 
					use crate::constants::StaticConstraints;
 | 
				
			||||||
 | 
					use crate::utils::countries_utils;
 | 
				
			||||||
 | 
					use crate::utils::countries_utils::CountryCode;
 | 
				
			||||||
use actix_web::{HttpResponse, Responder};
 | 
					use actix_web::{HttpResponse, Responder};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Default hello route
 | 
					/// Default hello route
 | 
				
			||||||
@@ -12,6 +14,7 @@ struct ServerConfig<'a> {
 | 
				
			|||||||
    constraints: StaticConstraints,
 | 
					    constraints: StaticConstraints,
 | 
				
			||||||
    mail: &'static str,
 | 
					    mail: &'static str,
 | 
				
			||||||
    oidc_providers: Vec<OIDCProvider<'a>>,
 | 
					    oidc_providers: Vec<OIDCProvider<'a>>,
 | 
				
			||||||
 | 
					    countries: Vec<CountryCode>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for ServerConfig<'_> {
 | 
					impl Default for ServerConfig<'_> {
 | 
				
			||||||
@@ -20,6 +23,7 @@ impl Default for ServerConfig<'_> {
 | 
				
			|||||||
            mail: AppConfig::get().mail_sender.as_str(),
 | 
					            mail: AppConfig::get().mail_sender.as_str(),
 | 
				
			||||||
            constraints: StaticConstraints::default(),
 | 
					            constraints: StaticConstraints::default(),
 | 
				
			||||||
            oidc_providers: AppConfig::get().openid_providers(),
 | 
					            oidc_providers: AppConfig::get().openid_providers(),
 | 
				
			||||||
 | 
					            countries: countries_utils::get_list(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ use actix_web::middleware::Logger;
 | 
				
			|||||||
use actix_web::{web, App, HttpServer};
 | 
					use actix_web::{web, App, HttpServer};
 | 
				
			||||||
use geneit_backend::app_config::AppConfig;
 | 
					use geneit_backend::app_config::AppConfig;
 | 
				
			||||||
use geneit_backend::controllers::{
 | 
					use geneit_backend::controllers::{
 | 
				
			||||||
    auth_controller, families_controller, server_controller, users_controller,
 | 
					    auth_controller, families_controller, members_controller, server_controller, users_controller,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[actix_web::main]
 | 
					#[actix_web::main]
 | 
				
			||||||
@@ -122,6 +122,11 @@ async fn main() -> std::io::Result<()> {
 | 
				
			|||||||
                "/family/{id}/user/{user_id}",
 | 
					                "/family/{id}/user/{user_id}",
 | 
				
			||||||
                web::delete().to(families_controller::delete_membership),
 | 
					                web::delete().to(families_controller::delete_membership),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
 | 
					            // Members controller
 | 
				
			||||||
 | 
					            .route(
 | 
				
			||||||
 | 
					                "/family/{id}/member/create",
 | 
				
			||||||
 | 
					                web::post().to(members_controller::create),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .bind(AppConfig::get().listen_address.as_str())?
 | 
					    .bind(AppConfig::get().listen_address.as_str())?
 | 
				
			||||||
    .run()
 | 
					    .run()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
use crate::schema::{families, memberships, users};
 | 
					use crate::schema::{families, members, memberships, users};
 | 
				
			||||||
use diesel::prelude::*;
 | 
					use diesel::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// User ID holder
 | 
					/// User ID holder
 | 
				
			||||||
@@ -116,3 +116,105 @@ pub struct FamilyMembership {
 | 
				
			|||||||
    pub count_members: i64,
 | 
					    pub count_members: i64,
 | 
				
			||||||
    pub count_admins: i64,
 | 
					    pub count_admins: i64,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Member ID holder
 | 
				
			||||||
 | 
					#[derive(Debug, Clone, Copy, serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
 | 
					pub struct MemberID(pub i32);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize, serde::Deserialize)]
 | 
				
			||||||
 | 
					pub enum Sex {
 | 
				
			||||||
 | 
					    #[serde(rename = "M")]
 | 
				
			||||||
 | 
					    Male,
 | 
				
			||||||
 | 
					    #[serde(rename = "F")]
 | 
				
			||||||
 | 
					    Female,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Sex {
 | 
				
			||||||
 | 
					    pub fn from_str(s: &str) -> Option<Self> {
 | 
				
			||||||
 | 
					        match s {
 | 
				
			||||||
 | 
					            "M" => Some(Sex::Male),
 | 
				
			||||||
 | 
					            "F" => Some(Sex::Female),
 | 
				
			||||||
 | 
					            _ => None,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn to_str(&self) -> &'static str {
 | 
				
			||||||
 | 
					        match self {
 | 
				
			||||||
 | 
					            Sex::Male => "M",
 | 
				
			||||||
 | 
					            Sex::Female => "F",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Queryable, Debug, serde::Serialize)]
 | 
				
			||||||
 | 
					pub struct Member {
 | 
				
			||||||
 | 
					    id: i32,
 | 
				
			||||||
 | 
					    family_id: i32,
 | 
				
			||||||
 | 
					    pub first_name: Option<String>,
 | 
				
			||||||
 | 
					    pub last_name: Option<String>,
 | 
				
			||||||
 | 
					    pub birth_last_name: Option<String>,
 | 
				
			||||||
 | 
					    pub photo_id: Option<String>,
 | 
				
			||||||
 | 
					    pub email: Option<String>,
 | 
				
			||||||
 | 
					    pub phone: Option<String>,
 | 
				
			||||||
 | 
					    pub address: Option<String>,
 | 
				
			||||||
 | 
					    pub city: Option<String>,
 | 
				
			||||||
 | 
					    pub postal_code: Option<String>,
 | 
				
			||||||
 | 
					    pub country: Option<String>,
 | 
				
			||||||
 | 
					    sex: Option<String>,
 | 
				
			||||||
 | 
					    time_create: i64,
 | 
				
			||||||
 | 
					    pub time_update: i64,
 | 
				
			||||||
 | 
					    mother: Option<i32>,
 | 
				
			||||||
 | 
					    father: Option<i32>,
 | 
				
			||||||
 | 
					    pub birth_year: Option<i16>,
 | 
				
			||||||
 | 
					    pub birth_month: Option<i16>,
 | 
				
			||||||
 | 
					    pub birth_day: Option<i16>,
 | 
				
			||||||
 | 
					    pub death_year: Option<i16>,
 | 
				
			||||||
 | 
					    pub death_month: Option<i16>,
 | 
				
			||||||
 | 
					    pub death_day: Option<i16>,
 | 
				
			||||||
 | 
					    pub note: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Member {
 | 
				
			||||||
 | 
					    pub fn id(&self) -> MemberID {
 | 
				
			||||||
 | 
					        MemberID(self.id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn family_id(&self) -> FamilyID {
 | 
				
			||||||
 | 
					        FamilyID(self.family_id)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn sex(&self) -> Option<Sex> {
 | 
				
			||||||
 | 
					        self.sex
 | 
				
			||||||
 | 
					            .as_deref()
 | 
				
			||||||
 | 
					            .map(|s| Sex::from_str(s))
 | 
				
			||||||
 | 
					            .unwrap_or_default()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_sex(&mut self, s: Option<Sex>) {
 | 
				
			||||||
 | 
					        self.sex = s.map(|s| s.to_str().to_string())
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn mother(&self) -> Option<MemberID> {
 | 
				
			||||||
 | 
					        self.mother.map(MemberID)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_mother(&mut self, p: Option<MemberID>) {
 | 
				
			||||||
 | 
					        self.mother = p.map(|p| p.0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn father(&self) -> Option<MemberID> {
 | 
				
			||||||
 | 
					        self.father.map(MemberID)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn set_father(&mut self, p: Option<MemberID>) {
 | 
				
			||||||
 | 
					        self.father = p.map(|p| p.0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Insertable)]
 | 
				
			||||||
 | 
					#[diesel(table_name = members)]
 | 
				
			||||||
 | 
					pub struct NewMember {
 | 
				
			||||||
 | 
					    pub family_id: i32,
 | 
				
			||||||
 | 
					    pub time_create: i64,
 | 
				
			||||||
 | 
					    pub time_update: i64,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@ diesel::table! {
 | 
				
			|||||||
        city -> Nullable<Varchar>,
 | 
					        city -> Nullable<Varchar>,
 | 
				
			||||||
        postal_code -> Nullable<Varchar>,
 | 
					        postal_code -> Nullable<Varchar>,
 | 
				
			||||||
        country -> Nullable<Varchar>,
 | 
					        country -> Nullable<Varchar>,
 | 
				
			||||||
        sex -> Varchar,
 | 
					        sex -> Nullable<Varchar>,
 | 
				
			||||||
        time_create -> Int8,
 | 
					        time_create -> Int8,
 | 
				
			||||||
        time_update -> Int8,
 | 
					        time_update -> Int8,
 | 
				
			||||||
        mother -> Nullable<Int4>,
 | 
					        mother -> Nullable<Int4>,
 | 
				
			||||||
@@ -82,10 +82,4 @@ diesel::joinable!(members -> families (family_id));
 | 
				
			|||||||
diesel::joinable!(memberships -> families (family_id));
 | 
					diesel::joinable!(memberships -> families (family_id));
 | 
				
			||||||
diesel::joinable!(memberships -> users (user_id));
 | 
					diesel::joinable!(memberships -> users (user_id));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
diesel::allow_tables_to_appear_in_same_query!(
 | 
					diesel::allow_tables_to_appear_in_same_query!(couples, families, members, memberships, users,);
 | 
				
			||||||
    couples,
 | 
					 | 
				
			||||||
    families,
 | 
					 | 
				
			||||||
    members,
 | 
					 | 
				
			||||||
    memberships,
 | 
					 | 
				
			||||||
    users,
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										91
									
								
								geneit_backend/src/services/members_service.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								geneit_backend/src/services/members_service.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					use crate::connections::db_connection;
 | 
				
			||||||
 | 
					use crate::models::{FamilyID, Member, MemberID, NewMember};
 | 
				
			||||||
 | 
					use crate::schema::members;
 | 
				
			||||||
 | 
					use crate::utils::time_utils::time;
 | 
				
			||||||
 | 
					use diesel::prelude::*;
 | 
				
			||||||
 | 
					use diesel::RunQueryDsl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Create a new family member
 | 
				
			||||||
 | 
					pub async fn create(family_id: FamilyID) -> anyhow::Result<Member> {
 | 
				
			||||||
 | 
					    db_connection::execute(|conn| {
 | 
				
			||||||
 | 
					        let res: Member = diesel::insert_into(members::table)
 | 
				
			||||||
 | 
					            .values(&NewMember {
 | 
				
			||||||
 | 
					                family_id: family_id.0,
 | 
				
			||||||
 | 
					                time_create: time() as i64,
 | 
				
			||||||
 | 
					                time_update: time() as i64,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .get_result(conn)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(res)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Get the information of a member
 | 
				
			||||||
 | 
					pub async fn get_by_id(id: MemberID) -> anyhow::Result<Member> {
 | 
				
			||||||
 | 
					    db_connection::execute(|conn| members::table.filter(members::dsl::id.eq(id.0)).first(conn))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Check whether a member with a given id exists or not
 | 
				
			||||||
 | 
					pub async fn exists(family_id: FamilyID, member_id: MemberID) -> anyhow::Result<bool> {
 | 
				
			||||||
 | 
					    db_connection::execute(|conn| {
 | 
				
			||||||
 | 
					        let count: i64 = members::table
 | 
				
			||||||
 | 
					            .filter(
 | 
				
			||||||
 | 
					                members::id
 | 
				
			||||||
 | 
					                    .eq(member_id.0)
 | 
				
			||||||
 | 
					                    .and(members::family_id.eq(family_id.0)),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .count()
 | 
				
			||||||
 | 
					            .get_result(conn)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(count != 0)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Update the information of a member
 | 
				
			||||||
 | 
					pub async fn update(member: &mut Member) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    member.time_update = time() as i64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    db_connection::execute(|conn| {
 | 
				
			||||||
 | 
					        diesel::update(members::dsl::members.filter(members::dsl::id.eq(member.id().0)))
 | 
				
			||||||
 | 
					            .set((
 | 
				
			||||||
 | 
					                members::dsl::first_name.eq(member.first_name.clone()),
 | 
				
			||||||
 | 
					                members::dsl::last_name.eq(member.last_name.clone()),
 | 
				
			||||||
 | 
					                members::dsl::birth_last_name.eq(member.birth_last_name.clone()),
 | 
				
			||||||
 | 
					                members::dsl::photo_id.eq(member.photo_id.clone()),
 | 
				
			||||||
 | 
					                members::dsl::email.eq(member.email.clone()),
 | 
				
			||||||
 | 
					                members::dsl::phone.eq(member.phone.clone()),
 | 
				
			||||||
 | 
					                members::dsl::address.eq(member.address.clone()),
 | 
				
			||||||
 | 
					                members::dsl::city.eq(member.city.clone()),
 | 
				
			||||||
 | 
					                members::dsl::postal_code.eq(member.postal_code.clone()),
 | 
				
			||||||
 | 
					                members::dsl::country.eq(member.country.clone()),
 | 
				
			||||||
 | 
					                members::dsl::sex.eq(member.sex().map(|s| s.to_str().to_string())),
 | 
				
			||||||
 | 
					                members::dsl::time_update.eq(member.time_update),
 | 
				
			||||||
 | 
					                members::dsl::mother.eq(member.mother().map(|m| m.0)),
 | 
				
			||||||
 | 
					                members::dsl::father.eq(member.father().map(|m| m.0)),
 | 
				
			||||||
 | 
					                members::dsl::birth_year.eq(member.birth_year),
 | 
				
			||||||
 | 
					                members::dsl::birth_month.eq(member.birth_month),
 | 
				
			||||||
 | 
					                members::dsl::birth_day.eq(member.birth_day),
 | 
				
			||||||
 | 
					                members::dsl::death_year.eq(member.death_year),
 | 
				
			||||||
 | 
					                members::dsl::death_month.eq(member.death_month),
 | 
				
			||||||
 | 
					                members::dsl::death_day.eq(member.death_day),
 | 
				
			||||||
 | 
					                members::dsl::note.eq(member.note.clone()),
 | 
				
			||||||
 | 
					            ))
 | 
				
			||||||
 | 
					            .execute(conn)
 | 
				
			||||||
 | 
					    })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Delete a member
 | 
				
			||||||
 | 
					pub async fn delete(member: &Member) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    // TODO : remove associated couple
 | 
				
			||||||
 | 
					    // TODO : remove user photo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Remove the member
 | 
				
			||||||
 | 
					    db_connection::execute(|conn| {
 | 
				
			||||||
 | 
					        diesel::delete(members::dsl::members.filter(members::dsl::id.eq(member.id().0)))
 | 
				
			||||||
 | 
					            .execute(conn)
 | 
				
			||||||
 | 
					    })?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -3,6 +3,7 @@
 | 
				
			|||||||
pub mod families_service;
 | 
					pub mod families_service;
 | 
				
			||||||
pub mod login_token_service;
 | 
					pub mod login_token_service;
 | 
				
			||||||
pub mod mail_service;
 | 
					pub mod mail_service;
 | 
				
			||||||
 | 
					pub mod members_service;
 | 
				
			||||||
pub mod openid_service;
 | 
					pub mod openid_service;
 | 
				
			||||||
pub mod rate_limiter_service;
 | 
					pub mod rate_limiter_service;
 | 
				
			||||||
pub mod users_service;
 | 
					pub mod users_service;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										48
									
								
								geneit_backend/src/utils/countries_utils.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								geneit_backend/src/utils/countries_utils.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
				
			|||||||
 | 
					use lazy_static::lazy_static;
 | 
				
			||||||
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lazy_static! {
 | 
				
			||||||
 | 
					    static ref COUNTRIES_FR: HashMap<String, String> =
 | 
				
			||||||
 | 
					        serde_json::from_str(include_str!("../../assets/iso-3166_country_french.json")).unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn is_code_valid(code: &str) -> bool {
 | 
				
			||||||
 | 
					    rust_iso3166::ALL_ALPHA2.contains(&code)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(serde::Serialize, Debug, Copy, Clone)]
 | 
				
			||||||
 | 
					pub struct CountryCode {
 | 
				
			||||||
 | 
					    code: &'static str,
 | 
				
			||||||
 | 
					    en: &'static str,
 | 
				
			||||||
 | 
					    fr: &'static str,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Get the entire list of countries
 | 
				
			||||||
 | 
					pub fn get_list() -> Vec<CountryCode> {
 | 
				
			||||||
 | 
					    rust_iso3166::ALL
 | 
				
			||||||
 | 
					        .iter()
 | 
				
			||||||
 | 
					        .map(|c| CountryCode {
 | 
				
			||||||
 | 
					            code: c.alpha2,
 | 
				
			||||||
 | 
					            en: c.name,
 | 
				
			||||||
 | 
					            fr: COUNTRIES_FR
 | 
				
			||||||
 | 
					                .get(c.alpha2)
 | 
				
			||||||
 | 
					                .map(|s| s.as_str())
 | 
				
			||||||
 | 
					                .unwrap_or(c.name),
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .collect()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod test {
 | 
				
			||||||
 | 
					    use crate::utils::countries_utils::is_code_valid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_code_fr() {
 | 
				
			||||||
 | 
					        assert!(is_code_valid("FR"))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_code_bad() {
 | 
				
			||||||
 | 
					        assert!(!is_code_valid("ZZ"))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
//! # App utilities
 | 
					//! # App utilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod countries_utils;
 | 
				
			||||||
pub mod string_utils;
 | 
					pub mod string_utils;
 | 
				
			||||||
pub mod time_utils;
 | 
					pub mod time_utils;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user