pub trait OrderingStrategy: Send + Sync {
fn fields(&self) -> Vec<String>;
fn description(&self) -> String {
format!("Ordering by: {}", self.fields().join(", "))
}
}
#[derive(Debug, Clone)]
pub struct CreatedAtOrdering {
pub created_field: String,
pub stable_field: String,
}
impl CreatedAtOrdering {
pub fn new() -> Self {
Self {
created_field: "created_at".to_string(),
stable_field: "id".to_string(),
}
}
pub fn with_fields(mut self, created: &str, stable: &str) -> Self {
self.created_field = created.to_string();
self.stable_field = stable.to_string();
self
}
}
impl Default for CreatedAtOrdering {
fn default() -> Self {
Self::new()
}
}
impl OrderingStrategy for CreatedAtOrdering {
fn fields(&self) -> Vec<String> {
vec![
format!("-{}", self.created_field),
self.stable_field.clone(),
]
}
}
#[derive(Debug, Clone)]
pub struct IdOrdering {
pub id_field: String,
pub ascending: bool,
}
impl IdOrdering {
pub fn new() -> Self {
Self {
id_field: "id".to_string(),
ascending: true,
}
}
pub fn descending() -> Self {
Self {
id_field: "id".to_string(),
ascending: false,
}
}
pub fn with_field(mut self, field: &str) -> Self {
self.id_field = field.to_string();
self
}
}
impl Default for IdOrdering {
fn default() -> Self {
Self::new()
}
}
impl OrderingStrategy for IdOrdering {
fn fields(&self) -> Vec<String> {
if self.ascending {
vec![self.id_field.clone()]
} else {
vec![format!("-{}", self.id_field)]
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_created_at_ordering_default() {
let ordering = CreatedAtOrdering::new();
assert_eq!(ordering.fields(), vec!["-created_at", "id"]);
}
#[test]
fn test_created_at_ordering_custom_fields() {
let ordering = CreatedAtOrdering::new().with_fields("created", "pk");
assert_eq!(ordering.fields(), vec!["-created", "pk"]);
}
#[test]
fn test_id_ordering_ascending() {
let ordering = IdOrdering::new();
assert_eq!(ordering.fields(), vec!["id"]);
assert!(ordering.ascending);
}
#[test]
fn test_id_ordering_descending() {
let ordering = IdOrdering::descending();
assert_eq!(ordering.fields(), vec!["-id"]);
assert!(!ordering.ascending);
}
#[test]
fn test_id_ordering_custom_field() {
let ordering = IdOrdering::new().with_field("pk");
assert_eq!(ordering.fields(), vec!["pk"]);
}
#[test]
fn test_ordering_description() {
let ordering = CreatedAtOrdering::new();
assert_eq!(ordering.description(), "Ordering by: -created_at, id");
}
}