Skip to content

Commit eb01e9e

Browse files
committed
Create a SynapseDuration rust class
This makes it easier to create a `Duration` instance in Rust.
1 parent 6078d5a commit eb01e9e

File tree

3 files changed

+61
-6
lines changed

3 files changed

+61
-6
lines changed

rust/src/duration.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* This file is licensed under the Affero General Public License (AGPL) version 3.
3+
*
4+
* Copyright (C) 2025 Element Creations, Ltd
5+
*
6+
* This program is free software: you can redistribute it and/or modify
7+
* it under the terms of the GNU Affero General Public License as
8+
* published by the Free Software Foundation, either version 3 of the
9+
* License, or (at your option) any later version.
10+
*
11+
* See the GNU Affero General Public License for more details:
12+
* <https://www.gnu.org/licenses/agpl-3.0.html>.
13+
*/
14+
15+
use once_cell::sync::OnceCell;
16+
use pyo3::{
17+
types::{IntoPyDict, PyAnyMethods},
18+
Bound, BoundObject, IntoPyObject, Py, PyAny, PyErr, PyResult, Python,
19+
};
20+
21+
/// A reference to the `synapse.util.duration` module.
22+
static DURATION: OnceCell<Py<PyAny>> = OnceCell::new();
23+
24+
/// Access to the `synapse.util.duration` module.
25+
fn duration_module(py: Python<'_>) -> PyResult<&Bound<'_, PyAny>> {
26+
Ok(DURATION
27+
.get_or_try_init(|| py.import("synapse.util.duration").map(Into::into))?
28+
.bind(py))
29+
}
30+
31+
/// Mirrors the `synapse.util.duration.Duration` Python class.
32+
pub struct SynapseDuration {
33+
microseconds: u64,
34+
}
35+
36+
impl SynapseDuration {
37+
/// For now we only need to create durations from milliseconds.
38+
pub fn from_milliseconds(milliseconds: u64) -> Self {
39+
Self {
40+
microseconds: milliseconds * 1_000,
41+
}
42+
}
43+
}
44+
45+
impl<'py> IntoPyObject<'py> for &SynapseDuration {
46+
type Target = PyAny;
47+
type Output = Bound<'py, Self::Target>;
48+
type Error = PyErr;
49+
50+
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
51+
let duration_module = duration_module(py)?;
52+
let kwargs = [("microseconds", self.microseconds)].into_py_dict(py)?;
53+
let duration_instance = duration_module.call_method("Duration", (), Some(&kwargs))?;
54+
Ok(duration_instance.into_bound())
55+
}
56+
}

rust/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use pyo3::prelude::*;
55
use pyo3_log::ResetHandle;
66

77
pub mod acl;
8+
pub mod duration;
89
pub mod errors;
910
pub mod events;
1011
pub mod http;

rust/src/rendezvous/mod.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@ use mime::Mime;
2828
use pyo3::{
2929
exceptions::PyValueError,
3030
pyclass, pymethods,
31-
types::{IntoPyDict, PyAnyMethods, PyModule, PyModuleMethods},
31+
types::{PyAnyMethods, PyModule, PyModuleMethods},
3232
Bound, IntoPyObject, Py, PyAny, PyResult, Python,
3333
};
3434
use ulid::Ulid;
3535

3636
use self::session::Session;
3737
use crate::{
38+
duration::SynapseDuration,
3839
errors::{NotFoundError, SynapseError},
3940
http::{http_request_from_twisted, http_response_to_twisted, HeaderMapPyExt},
4041
UnwrapInfallible,
@@ -132,10 +133,7 @@ impl RendezvousHandler {
132133
.unwrap_infallible()
133134
.unbind();
134135

135-
let duration_module = py.import("synapse.util.duration")?;
136-
137-
let kwargs = [("milliseconds", eviction_interval)].into_py_dict(py)?;
138-
let eviction_duration = duration_module.call_method("Duration", (), Some(&kwargs))?;
136+
let eviction_duration = SynapseDuration::from_milliseconds(eviction_interval);
139137

140138
// Construct a Python object so that we can get a reference to the
141139
// evict method and schedule it to run.
@@ -154,7 +152,7 @@ impl RendezvousHandler {
154152
let evict = self_.getattr(py, "_evict")?;
155153
homeserver.call_method0("get_clock")?.call_method(
156154
"looping_call",
157-
(evict, eviction_duration),
155+
(evict, &eviction_duration),
158156
None,
159157
)?;
160158

0 commit comments

Comments
 (0)