This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

rust version

+575
+2
.gitignore
··· 1 + /target 2 + participants.toml
+405
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 4 4 + 5 + [[package]] 6 + name = "anstream" 7 + version = "0.6.21" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" 10 + dependencies = [ 11 + "anstyle", 12 + "anstyle-parse", 13 + "anstyle-query", 14 + "anstyle-wincon", 15 + "colorchoice", 16 + "is_terminal_polyfill", 17 + "utf8parse", 18 + ] 19 + 20 + [[package]] 21 + name = "anstyle" 22 + version = "1.0.13" 23 + source = "registry+https://github.com/rust-lang/crates.io-index" 24 + checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" 25 + 26 + [[package]] 27 + name = "anstyle-parse" 28 + version = "0.2.7" 29 + source = "registry+https://github.com/rust-lang/crates.io-index" 30 + checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" 31 + dependencies = [ 32 + "utf8parse", 33 + ] 34 + 35 + [[package]] 36 + name = "anstyle-query" 37 + version = "1.1.5" 38 + source = "registry+https://github.com/rust-lang/crates.io-index" 39 + checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" 40 + dependencies = [ 41 + "windows-sys", 42 + ] 43 + 44 + [[package]] 45 + name = "anstyle-wincon" 46 + version = "3.0.11" 47 + source = "registry+https://github.com/rust-lang/crates.io-index" 48 + checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" 49 + dependencies = [ 50 + "anstyle", 51 + "once_cell_polyfill", 52 + "windows-sys", 53 + ] 54 + 55 + [[package]] 56 + name = "base64" 57 + version = "0.22.1" 58 + source = "registry+https://github.com/rust-lang/crates.io-index" 59 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 60 + 61 + [[package]] 62 + name = "cfg-if" 63 + version = "1.0.4" 64 + source = "registry+https://github.com/rust-lang/crates.io-index" 65 + checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" 66 + 67 + [[package]] 68 + name = "clap" 69 + version = "4.5.53" 70 + source = "registry+https://github.com/rust-lang/crates.io-index" 71 + checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" 72 + dependencies = [ 73 + "clap_builder", 74 + "clap_derive", 75 + ] 76 + 77 + [[package]] 78 + name = "clap_builder" 79 + version = "4.5.53" 80 + source = "registry+https://github.com/rust-lang/crates.io-index" 81 + checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" 82 + dependencies = [ 83 + "anstream", 84 + "anstyle", 85 + "clap_lex", 86 + "strsim", 87 + ] 88 + 89 + [[package]] 90 + name = "clap_derive" 91 + version = "4.5.49" 92 + source = "registry+https://github.com/rust-lang/crates.io-index" 93 + checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" 94 + dependencies = [ 95 + "heck", 96 + "proc-macro2", 97 + "quote", 98 + "syn", 99 + ] 100 + 101 + [[package]] 102 + name = "clap_lex" 103 + version = "0.7.6" 104 + source = "registry+https://github.com/rust-lang/crates.io-index" 105 + checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" 106 + 107 + [[package]] 108 + name = "colorchoice" 109 + version = "1.0.4" 110 + source = "registry+https://github.com/rust-lang/crates.io-index" 111 + checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" 112 + 113 + [[package]] 114 + name = "equivalent" 115 + version = "1.0.2" 116 + source = "registry+https://github.com/rust-lang/crates.io-index" 117 + checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 118 + 119 + [[package]] 120 + name = "getrandom" 121 + version = "0.3.4" 122 + source = "registry+https://github.com/rust-lang/crates.io-index" 123 + checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" 124 + dependencies = [ 125 + "cfg-if", 126 + "libc", 127 + "r-efi", 128 + "wasip2", 129 + ] 130 + 131 + [[package]] 132 + name = "hashbrown" 133 + version = "0.16.1" 134 + source = "registry+https://github.com/rust-lang/crates.io-index" 135 + checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" 136 + 137 + [[package]] 138 + name = "heck" 139 + version = "0.5.0" 140 + source = "registry+https://github.com/rust-lang/crates.io-index" 141 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 142 + 143 + [[package]] 144 + name = "indexmap" 145 + version = "2.12.1" 146 + source = "registry+https://github.com/rust-lang/crates.io-index" 147 + checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" 148 + dependencies = [ 149 + "equivalent", 150 + "hashbrown", 151 + ] 152 + 153 + [[package]] 154 + name = "is_terminal_polyfill" 155 + version = "1.70.2" 156 + source = "registry+https://github.com/rust-lang/crates.io-index" 157 + checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" 158 + 159 + [[package]] 160 + name = "libc" 161 + version = "0.2.177" 162 + source = "registry+https://github.com/rust-lang/crates.io-index" 163 + checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" 164 + 165 + [[package]] 166 + name = "once_cell_polyfill" 167 + version = "1.70.2" 168 + source = "registry+https://github.com/rust-lang/crates.io-index" 169 + checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" 170 + 171 + [[package]] 172 + name = "ppv-lite86" 173 + version = "0.2.21" 174 + source = "registry+https://github.com/rust-lang/crates.io-index" 175 + checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" 176 + dependencies = [ 177 + "zerocopy", 178 + ] 179 + 180 + [[package]] 181 + name = "proc-macro2" 182 + version = "1.0.103" 183 + source = "registry+https://github.com/rust-lang/crates.io-index" 184 + checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" 185 + dependencies = [ 186 + "unicode-ident", 187 + ] 188 + 189 + [[package]] 190 + name = "quote" 191 + version = "1.0.42" 192 + source = "registry+https://github.com/rust-lang/crates.io-index" 193 + checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" 194 + dependencies = [ 195 + "proc-macro2", 196 + ] 197 + 198 + [[package]] 199 + name = "r-efi" 200 + version = "5.3.0" 201 + source = "registry+https://github.com/rust-lang/crates.io-index" 202 + checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" 203 + 204 + [[package]] 205 + name = "rand" 206 + version = "0.9.2" 207 + source = "registry+https://github.com/rust-lang/crates.io-index" 208 + checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" 209 + dependencies = [ 210 + "rand_chacha", 211 + "rand_core", 212 + ] 213 + 214 + [[package]] 215 + name = "rand_chacha" 216 + version = "0.9.0" 217 + source = "registry+https://github.com/rust-lang/crates.io-index" 218 + checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" 219 + dependencies = [ 220 + "ppv-lite86", 221 + "rand_core", 222 + ] 223 + 224 + [[package]] 225 + name = "rand_core" 226 + version = "0.9.3" 227 + source = "registry+https://github.com/rust-lang/crates.io-index" 228 + checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" 229 + dependencies = [ 230 + "getrandom", 231 + ] 232 + 233 + [[package]] 234 + name = "secret-santa" 235 + version = "0.1.0" 236 + dependencies = [ 237 + "base64", 238 + "clap", 239 + "rand", 240 + "serde", 241 + "toml", 242 + ] 243 + 244 + [[package]] 245 + name = "serde" 246 + version = "1.0.228" 247 + source = "registry+https://github.com/rust-lang/crates.io-index" 248 + checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" 249 + dependencies = [ 250 + "serde_core", 251 + "serde_derive", 252 + ] 253 + 254 + [[package]] 255 + name = "serde_core" 256 + version = "1.0.228" 257 + source = "registry+https://github.com/rust-lang/crates.io-index" 258 + checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" 259 + dependencies = [ 260 + "serde_derive", 261 + ] 262 + 263 + [[package]] 264 + name = "serde_derive" 265 + version = "1.0.228" 266 + source = "registry+https://github.com/rust-lang/crates.io-index" 267 + checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" 268 + dependencies = [ 269 + "proc-macro2", 270 + "quote", 271 + "syn", 272 + ] 273 + 274 + [[package]] 275 + name = "serde_spanned" 276 + version = "1.0.3" 277 + source = "registry+https://github.com/rust-lang/crates.io-index" 278 + checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" 279 + dependencies = [ 280 + "serde_core", 281 + ] 282 + 283 + [[package]] 284 + name = "strsim" 285 + version = "0.11.1" 286 + source = "registry+https://github.com/rust-lang/crates.io-index" 287 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 288 + 289 + [[package]] 290 + name = "syn" 291 + version = "2.0.111" 292 + source = "registry+https://github.com/rust-lang/crates.io-index" 293 + checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" 294 + dependencies = [ 295 + "proc-macro2", 296 + "quote", 297 + "unicode-ident", 298 + ] 299 + 300 + [[package]] 301 + name = "toml" 302 + version = "0.9.8" 303 + source = "registry+https://github.com/rust-lang/crates.io-index" 304 + checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" 305 + dependencies = [ 306 + "indexmap", 307 + "serde_core", 308 + "serde_spanned", 309 + "toml_datetime", 310 + "toml_parser", 311 + "toml_writer", 312 + "winnow", 313 + ] 314 + 315 + [[package]] 316 + name = "toml_datetime" 317 + version = "0.7.3" 318 + source = "registry+https://github.com/rust-lang/crates.io-index" 319 + checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" 320 + dependencies = [ 321 + "serde_core", 322 + ] 323 + 324 + [[package]] 325 + name = "toml_parser" 326 + version = "1.0.4" 327 + source = "registry+https://github.com/rust-lang/crates.io-index" 328 + checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" 329 + dependencies = [ 330 + "winnow", 331 + ] 332 + 333 + [[package]] 334 + name = "toml_writer" 335 + version = "1.0.4" 336 + source = "registry+https://github.com/rust-lang/crates.io-index" 337 + checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" 338 + 339 + [[package]] 340 + name = "unicode-ident" 341 + version = "1.0.22" 342 + source = "registry+https://github.com/rust-lang/crates.io-index" 343 + checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" 344 + 345 + [[package]] 346 + name = "utf8parse" 347 + version = "0.2.2" 348 + source = "registry+https://github.com/rust-lang/crates.io-index" 349 + checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 350 + 351 + [[package]] 352 + name = "wasip2" 353 + version = "1.0.1+wasi-0.2.4" 354 + source = "registry+https://github.com/rust-lang/crates.io-index" 355 + checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" 356 + dependencies = [ 357 + "wit-bindgen", 358 + ] 359 + 360 + [[package]] 361 + name = "windows-link" 362 + version = "0.2.1" 363 + source = "registry+https://github.com/rust-lang/crates.io-index" 364 + checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" 365 + 366 + [[package]] 367 + name = "windows-sys" 368 + version = "0.61.2" 369 + source = "registry+https://github.com/rust-lang/crates.io-index" 370 + checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" 371 + dependencies = [ 372 + "windows-link", 373 + ] 374 + 375 + [[package]] 376 + name = "winnow" 377 + version = "0.7.13" 378 + source = "registry+https://github.com/rust-lang/crates.io-index" 379 + checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" 380 + 381 + [[package]] 382 + name = "wit-bindgen" 383 + version = "0.46.0" 384 + source = "registry+https://github.com/rust-lang/crates.io-index" 385 + checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" 386 + 387 + [[package]] 388 + name = "zerocopy" 389 + version = "0.8.28" 390 + source = "registry+https://github.com/rust-lang/crates.io-index" 391 + checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" 392 + dependencies = [ 393 + "zerocopy-derive", 394 + ] 395 + 396 + [[package]] 397 + name = "zerocopy-derive" 398 + version = "0.8.28" 399 + source = "registry+https://github.com/rust-lang/crates.io-index" 400 + checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" 401 + dependencies = [ 402 + "proc-macro2", 403 + "quote", 404 + "syn", 405 + ]
+11
Cargo.toml
··· 1 + [package] 2 + name = "secret-santa" 3 + version = "0.1.0" 4 + edition = "2024" 5 + 6 + [dependencies] 7 + base64 = "0.22.1" 8 + clap = { version = "4.5.53", features = ["derive"] } 9 + rand = "0.9.2" 10 + serde = { version = "1.0.228", features = ["derive"] } 11 + toml = "0.9.8"
+13
example_participants.toml
··· 1 + participants = [ 2 + "Alice", 3 + "Bob", 4 + "Charlie", 5 + "David", 6 + "Eve", 7 + "Frank" 8 + ] 9 + 10 + exclusions = [ 11 + ["Alice", "Bob"], 12 + ["Charlie", "David"] 13 + ]
main.c old/main.c
+144
src/main.rs
··· 1 + use base64::prelude::*; 2 + use clap::Parser; 3 + use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng}; 4 + use serde::Deserialize; 5 + use std::collections::{HashMap, HashSet}; 6 + use std::fs; 7 + use std::time::{SystemTime, UNIX_EPOCH}; 8 + 9 + #[derive(Parser)] 10 + #[command(author, version, about, long_about = None)] 11 + struct Args { 12 + #[arg(short, long)] 13 + seed: Option<u64>, 14 + 15 + #[arg(short, long, default_value = "participants.toml")] 16 + config: String, 17 + 18 + #[arg(short, long)] 19 + debug: bool, 20 + } 21 + 22 + #[derive(Deserialize)] 23 + struct SantaConfig { 24 + participants: Vec<String>, 25 + exclusions: Option<Vec<Vec<String>>>, 26 + } 27 + 28 + fn main() { 29 + let args = Args::parse(); 30 + 31 + let seed = args.seed.unwrap_or_else(|| { 32 + SystemTime::now() 33 + .duration_since(UNIX_EPOCH) 34 + .expect("Time went backwards") 35 + .as_secs() 36 + }); 37 + 38 + println!("Seed: {}", seed); 39 + 40 + let content = match fs::read_to_string(&args.config) { 41 + Ok(c) => c, 42 + Err(e) => { 43 + eprintln!("Could not read file '{}': {}", args.config, e); 44 + return; 45 + } 46 + }; 47 + 48 + let config: SantaConfig = match toml::from_str(&content) { 49 + Ok(c) => c, 50 + Err(e) => { 51 + eprintln!("Error parsing TOML: {}", e); 52 + return; 53 + } 54 + }; 55 + 56 + let names = config.participants; 57 + 58 + if names.len() < 3 { 59 + eprintln!("Need at least three participants to avoid bi-directional pairing."); 60 + return; 61 + } 62 + 63 + let mut forbidden_pairs: HashSet<(String, String)> = HashSet::new(); 64 + if let Some(excl_list) = config.exclusions { 65 + for pair in excl_list { 66 + if pair.len() == 2 { 67 + forbidden_pairs.insert((pair[0].clone(), pair[1].clone())); 68 + forbidden_pairs.insert((pair[1].clone(), pair[0].clone())); 69 + } 70 + } 71 + } 72 + 73 + let mut rng = StdRng::seed_from_u64(seed); 74 + let mut assignments: HashMap<String, String> = HashMap::new(); 75 + let mut receiver_pool = names.clone(); 76 + 77 + if solve_allocations( 78 + &names, 79 + 0, 80 + &mut receiver_pool, 81 + &mut assignments, 82 + &forbidden_pairs, 83 + &mut rng, 84 + ) { 85 + for giver in &names { 86 + let receiver = assignments.get(giver).unwrap(); 87 + if args.debug { 88 + println!("{}: {}", giver, receiver); 89 + } else { 90 + let encoded = BASE64_STANDARD.encode(receiver); 91 + println!("{}: {}", giver, encoded); 92 + } 93 + } 94 + } else { 95 + eprintln!("Error: Could not find a valid arrangement with these constraints."); 96 + } 97 + } 98 + 99 + fn solve_allocations( 100 + givers: &Vec<String>, 101 + giver_index: usize, 102 + receiver_pool: &mut Vec<String>, 103 + assignments: &mut HashMap<String, String>, 104 + forbidden: &HashSet<(String, String)>, 105 + rng: &mut StdRng, 106 + ) -> bool { 107 + if giver_index >= givers.len() { 108 + return true; 109 + } 110 + 111 + let current_giver = &givers[giver_index]; 112 + let mut candidates = receiver_pool.clone(); 113 + candidates.shuffle(rng); 114 + 115 + for candidate in candidates { 116 + if candidate == *current_giver { 117 + continue; 118 + } 119 + 120 + if forbidden.contains(&(current_giver.clone(), candidate.clone())) { 121 + continue; 122 + } 123 + 124 + if let Some(candidates_receiver) = assignments.get(&candidate) { 125 + if *candidates_receiver == *current_giver { 126 + continue; 127 + } 128 + } 129 + 130 + assignments.insert(current_giver.clone(), candidate.clone()); 131 + 132 + let index_in_pool = receiver_pool.iter().position(|x| *x == candidate).unwrap(); 133 + receiver_pool.remove(index_in_pool); 134 + 135 + if solve_allocations(givers, giver_index + 1, receiver_pool, assignments, forbidden, rng) { 136 + return true; 137 + } 138 + 139 + receiver_pool.insert(index_in_pool, candidate); 140 + assignments.remove(current_giver); 141 + } 142 + 143 + false 144 + }