1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
/*
Project: thormotion
GitHub: https://github.com/MillieFD/thormotion
BSD 3-Clause License, Copyright (c) 2025, Amelia Fraser-Dale
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the conditions of the LICENSE are met.
*/
use Display;
use ;
use ;
use ;
use crateError;
/* ---------------------------------------------------------------------------- Public Functions */
/// Returns an iterator over all connected Thorlabs USB devices.
/// For convenience, this function prints a list of connected Thorlabs USB devices to stdout.
/* --------------------------------------------------------------------------- Private Functions */
/// A lazily initialised [`HashMap`] containing the `serial number` (key) and [`abort function`][1]
/// (value) for each connected [`Thorlabs Device`][2]. It is protected by an async [`Mutex`] for
/// thread-safe concurrent access.
///
/// The [`HashMap`] is only accessed when connecting or disconnecting [`Thorlabs Devices`][2]. The
/// [`HashMap`] is not required when [`opening`][3], [`closing`][4], or [`sending`][5] commands to
/// the device. As such, lock contention does not affect device latency.
///
/// If an irrecoverable error occurs anywhere in the program, this triggers the [`abort`]
/// function that safely [`aborts`][1] each device, bringing the system to a controlled stop.
///
/// [1]: crate::traits::ThorlabsDevice::abort
/// [2]: crate::traits::ThorlabsDevice
/// [3]: crate::devices::UsbPrimitive::open
/// [4]: crate::devices::UsbPrimitive::close
/// [5]: crate::devices::UsbPrimitive::send
static DEVICES: = new;
/// Returns a [`MutexGuard`] protecting access to the global [`DEVICES`][1] [`HashMap`]. The map is
/// lazily initialised when first accessed.
///
/// ### Panics
///
/// Calls [`abort`] if the mutex is poisoned, safely stopping all devices before terminating
/// the program.
///
/// [1]: DEVICES
/// Adds a new [`Thorlabs Device`][1] `serial number` (key) and corresponding [`abort`][2] function
/// (value) to the global [`DEVICES`][3] [`HashMap`].
///
/// [1]: crate::traits::ThorlabsDevice
/// [2]: crate::traits::ThorlabsDevice::abort
/// [3]: DEVICES
pub
/// Removes the specified [`Thorlabs Device`][1] from the global [`DEVICES`][2] [`HashMap`]. Then
/// calls the corresponding [`abort`][2] function.
///
/// [1]: crate::traits::ThorlabsDevice
/// [2]: DEVICES
pub
/// Calls the [`abort`][1] function for the specified [`Thorlabs Device`][1].
///
/// The device is not removed from the global [`DEVICES`][2] [`HashMap`]. You can use
/// [`Open`][3] to resume communication.
///
/// [1]: crate::traits::ThorlabsDevice::abort
/// [2]: DEVICES
/// [3]: crate::devices::UsbPrimitive::open
pub
// SAFETY: This is a placeholder function. DO NOT USE.
/// Removes the specified [`Thorlabs Device`][1] from the global [`DEVICES`][2] [`HashMap`] without
/// calling the corresponding [`abort`][2] or [`close`][3] functions.
///
/// [1]: crate::traits::ThorlabsDevice
/// [2]: crate::traits::ThorlabsDevice::abort
/// [3]: crate::devices::UsbPrimitive::close
/// Safely stops all [`Thorlabs devices`][1], cleans up resources, and terminates the program with
/// an error message.
///
/// Internally, this function iterates over the global [`DEVICES`][2] [`HashMap`] and calls the
/// respective [`abort`][3] function for each device. To handle situations that should never occur,
/// see [`bug_abort`].
///
/// ### Panics
///
/// This function always panics.
///
/// This is intended behaviour to safely unwind and free resources.
///
/// [1]: crate::traits::ThorlabsDevice
/// [2]: DEVICES
/// [3]: crate::traits::ThorlabsDevice::abort
pub !
where
A: Display,
/// Safely stops all [`Thorlabs devices`][1], cleans up resources, and terminates the program with
/// an error message. Explains that the error is a bug and encourages the user to open a new GitHub
/// issue.
///
/// Internally, this function calls [`abort`] with an additional message.
///
/// ### Panics
///
/// This function always panics.
///
/// This is intended behaviour to safely unwind and free resources.
///
/// [1]: crate::traits::ThorlabsDevice
/// [2]: DEVICES
/// [3]: crate::traits::ThorlabsDevice::abort
pub !
/// Returns [`DeviceInfo`] for the Thorlabs device with the specified serial number.
///
/// Returns [`Error::NotFound`] if the specified device is not connected.
///
/// Returns [`Error::Multiple`] if more than one device with the specified serial number is found.
pub