Skip to content
This repository was archived by the owner on Jan 2, 2026. It is now read-only.

Commit 15d3385

Browse files
committed
feat: add try_generate_unique_random
1 parent 38897ac commit 15d3385

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

.sqlx/query-7f6feee74201f656db689fd9b194d5300406127707d3b5ccf73af7c97c443d18.json

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/database/serial_number.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
use bigdecimal::num_bigint::BigUint;
2+
use log::error;
23
use rand::TryRngCore;
3-
use sqlx::{Decode, Encode, Postgres, Type, types::BigDecimal};
4+
use sqlx::{Decode, Encode, Postgres, Type, query, types::BigDecimal};
5+
6+
use crate::{database::Database, errors::Error};
47

58
// TODO: This could be in polyproto instead
69

@@ -9,6 +12,48 @@ use sqlx::{Decode, Encode, Postgres, Type, types::BigDecimal};
912
pub struct SerialNumber(BigDecimal);
1013

1114
impl SerialNumber {
15+
/// Tries to generate a [SerialNumber] which does not yet exist in the
16+
/// `idcsr` table and its' `serial_number` column.
17+
///
18+
/// Calls [Self::try_generate_random] internally.
19+
///
20+
/// ## Errors
21+
///
22+
/// Will error, if:
23+
///
24+
/// - The [ThreadRng] fails to generate randomness. Depending on the
25+
/// implementation of `ThreadRng`, this method may cause a panic in these
26+
/// cases.
27+
/// - The database or database connection is unavailable for any reason.
28+
pub(crate) async fn try_generate_unique_random(
29+
db: &Database,
30+
rng: &mut rand::rngs::ThreadRng,
31+
) -> Result<Self, Error> {
32+
let mut serial_number =
33+
SerialNumber::try_generate_random(&mut rand::rng()).map_err(|e| {
34+
error!("Error while trying to generate serial_number: {e}");
35+
Error::new_internal_error(None)
36+
})?;
37+
while (query!(
38+
"
39+
SELECT serial_number
40+
FROM idcsr
41+
WHERE serial_number = $1
42+
",
43+
serial_number.as_bigdecimal()
44+
)
45+
.fetch_optional(&db.pool)
46+
.await?)
47+
.is_some()
48+
{
49+
serial_number = SerialNumber::try_generate_random(rng).map_err(|e| {
50+
error!("Error while trying to generate serial_number: {e}");
51+
Error::new_internal_error(None)
52+
})?;
53+
}
54+
Ok(serial_number)
55+
}
56+
1257
/// From a [ThreadRng], get 20 octets (160 bits) of entropy and construct a
1358
/// serial number out of it.
1459
///

0 commit comments

Comments
 (0)