I have the following structs:
use std::sync::Mutex;
pub struct Message {
id: String,
content: String,
last_read: Option<String>,
uuid: String,
}
impl Message {
pub fn get_uuid(&self) -> String {
self.uuid.to_owned()
}
}
pub struct Queue {
queue: Vec<Message>, // the actual queue
read_timeout: u32, // the amount of time a message is hidden from consumers
size: u32, // should always be the same as queue.len()
uuid: String,
}
pub struct AppState {
pub queues: Mutex<Vec<Queue>>,
}
Finally, I have some functions that do something with the data. They have duplicate logic, as you can see below. What they do after they get the queue
is different, but the way to retrieve the queue is the same.
pub async fn add_message(
data: AppState
) {
let queue_uuid = &String::from("my uuid");
let queue_mutex = data.queues.lock();
let mut queues = match queue_mutex {
Ok(q) => q,
Err(_) => return,
};
// find matching queue
let queue = queues.iter_mut().find(|q| q.uuid == *queue_uuid);
}
pub async fn get_message(
data: AppState
) {
let queue_uuid = &String::from("my uuid");
let queue_mutex = data.queues.lock();
let mut queues = match queue_mutex {
Ok(q) => q,
Err(_) => return,
};
// find matching queue
let queue = queues.iter_mut().find(|q| q.uuid == *queue_uuid);
// once the queue is found, do some stuff with it
}
I would like to dedup this logic.
impl AppState {
pub fn get_queues(&self) -> &Mutex<Vec<Queue>> {
&self.queues
}
pub fn get_queue_by_id(&mut self, uuid: String) -> Result<&mut Queue, String> {
let queue_mutex = self.queues.lock();
let mut queues = match queue_mutex {
Ok(q) => q,
Err(_) => return Err(String::from("Whoops! Something went wrong")),
};
match queues.iter_mut().find(|q| q.uuid == uuid) {
None => Err(format!("Could not find queue with uuid {}", uuid)),
Some(q) => Ok(q),
}
}
}
However, this will yield an error because I cannot return q
as it will be dropped when the function returns. Is there a good solution to this?
P.S: I know that a lot of this could be more efficient - i.e. using a hash map instead of vector to store the current queues. I am a Rust newbie and intend on refactoring a lot of this, so any feedback is helpful! Thanks!