mirror of
https://github.com/chatmail/core.git
synced 2026-04-06 15:42:10 +03:00
Co-Authored-By: bjoern <r10s@b44t.com> Co-Authored-By: Simon Laux <mobile.info@simonlaux.de>
140 lines
3.8 KiB
Rust
140 lines
3.8 KiB
Rust
use crate::chat::ChatItem;
|
|
use crate::constants::DC_MSG_ID_DAYMARKER;
|
|
use crate::contact::ContactId;
|
|
use crate::location::Location;
|
|
use crate::message::MsgId;
|
|
|
|
/* * the structure behind dc_array_t */
|
|
#[derive(Debug, Clone)]
|
|
pub enum dc_array_t {
|
|
MsgIds(Vec<MsgId>),
|
|
ContactIds(Vec<ContactId>),
|
|
Chat(Vec<ChatItem>),
|
|
Locations(Vec<Location>),
|
|
Uint(Vec<u32>),
|
|
}
|
|
|
|
impl dc_array_t {
|
|
pub(crate) fn get_id(&self, index: usize) -> u32 {
|
|
match self {
|
|
Self::MsgIds(array) => array[index].to_u32(),
|
|
Self::ContactIds(array) => array[index].to_u32(),
|
|
Self::Chat(array) => match array[index] {
|
|
ChatItem::Message { msg_id } => msg_id.to_u32(),
|
|
ChatItem::DayMarker { .. } => DC_MSG_ID_DAYMARKER,
|
|
},
|
|
Self::Locations(array) => array[index].location_id,
|
|
Self::Uint(array) => array[index],
|
|
}
|
|
}
|
|
|
|
pub(crate) fn get_timestamp(&self, index: usize) -> Option<i64> {
|
|
match self {
|
|
Self::MsgIds(_) => None,
|
|
Self::ContactIds(_) => None,
|
|
Self::Chat(array) => array.get(index).and_then(|item| match item {
|
|
ChatItem::Message { .. } => None,
|
|
ChatItem::DayMarker { timestamp } => Some(*timestamp),
|
|
}),
|
|
Self::Locations(array) => array.get(index).map(|location| location.timestamp),
|
|
Self::Uint(_) => None,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn get_marker(&self, index: usize) -> Option<&str> {
|
|
match self {
|
|
Self::MsgIds(_) => None,
|
|
Self::ContactIds(_) => None,
|
|
Self::Chat(_) => None,
|
|
Self::Locations(array) => array
|
|
.get(index)
|
|
.and_then(|location| location.marker.as_deref()),
|
|
Self::Uint(_) => None,
|
|
}
|
|
}
|
|
|
|
pub(crate) fn get_location(&self, index: usize) -> &Location {
|
|
if let Self::Locations(array) = self {
|
|
&array[index]
|
|
} else {
|
|
panic!("Not an array of locations")
|
|
}
|
|
}
|
|
|
|
/// Returns the number of elements in the array.
|
|
pub(crate) fn len(&self) -> usize {
|
|
match self {
|
|
Self::MsgIds(array) => array.len(),
|
|
Self::ContactIds(array) => array.len(),
|
|
Self::Chat(array) => array.len(),
|
|
Self::Locations(array) => array.len(),
|
|
Self::Uint(array) => array.len(),
|
|
}
|
|
}
|
|
|
|
pub(crate) fn search_id(&self, needle: u32) -> Option<usize> {
|
|
(0..self.len()).find(|i| self.get_id(*i) == needle)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<u32>> for dc_array_t {
|
|
fn from(array: Vec<u32>) -> Self {
|
|
dc_array_t::Uint(array)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<MsgId>> for dc_array_t {
|
|
fn from(array: Vec<MsgId>) -> Self {
|
|
dc_array_t::MsgIds(array)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<ContactId>> for dc_array_t {
|
|
fn from(array: Vec<ContactId>) -> Self {
|
|
dc_array_t::ContactIds(array)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<ChatItem>> for dc_array_t {
|
|
fn from(array: Vec<ChatItem>) -> Self {
|
|
dc_array_t::Chat(array)
|
|
}
|
|
}
|
|
|
|
impl From<Vec<Location>> for dc_array_t {
|
|
fn from(array: Vec<Location>) -> Self {
|
|
dc_array_t::Locations(array)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_dc_array() {
|
|
let arr: dc_array_t = Vec::<u32>::new().into();
|
|
assert!(arr.len() == 0);
|
|
|
|
let ids: Vec<u32> = (2..1002).collect();
|
|
let arr: dc_array_t = ids.into();
|
|
|
|
assert_eq!(arr.len(), 1000);
|
|
|
|
for i in 0..1000 {
|
|
assert_eq!(arr.get_id(i), (i + 2) as u32);
|
|
}
|
|
|
|
assert_eq!(arr.search_id(10), Some(8));
|
|
assert_eq!(arr.search_id(1), None);
|
|
}
|
|
|
|
#[test]
|
|
#[should_panic]
|
|
fn test_dc_array_out_of_bounds() {
|
|
let ids: Vec<u32> = (2..1002).collect();
|
|
let arr: dc_array_t = ids.into();
|
|
arr.get_id(1000);
|
|
}
|
|
}
|