use std::cmp::Ordering;
use std::collections::HashSet;
// As an artist, I can add artwork and attach it to a product
// As an artist, I can enter detailed information about a product
// As an artist, I can store a product for later recall by me or connoisseurs.
// As a connoisseur, I can search the gallery for artwork matching given keywords and see products
// containing that artwork
// As a connoisseur, I can select one or many products and submit them in a job to an artist
// As an artist, I can select individual products to be featured, and rank first in default fetch lists
// As an artist, I can select individual products to be featured, and rank first in search results
// As an artist, I can select entire categories to be featured, and rank first in search results
// As an artist, I can select entire categories to be featured, and rank first in default fetch
// lists
// Sellable artwork, artowrk with a price attached to it. Prices are in cents to do comparisons to
// other products without fractions. Has a quantity to indicate stock. Can be
// featured in order to appear higher in connoisseur search results.
#[derive(Debug, Clone)]
struct Product {
artwork: Artwork,
cents: u64,
quantity: u64,
featured: bool,
}
impl PartialEq for Product {
fn eq(&self, other: &Self) -> bool {
self.cents == other.cents
}
}
impl PartialOrd for Product {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.cents.partial_cmp(&other.cents)
}
}
impl Product {
fn dollars(&self) -> f64 {
self.cents as f64 / 100.0
}
}
#[derive(Debug, Clone)]
struct Artwork {
name: String,
description: String,
category: Vec<String>,
tags: HashSet<String>,
}
struct Customer {}
trait Artist {
fn create_art<G: Gallery>(gallery: G) -> Result<(), ()>;
}
struct Sort {
highest_price: bool,
lowest_price: bool,
highest_quantity: bool,
lowest_quantity: bool,
atoz: bool,
ztoa: bool,
oldest: bool,
newest: bool,
featured: bool,
}
struct Filter {
search_term: HashSet<String>,
category: Vec<String>,
sort: Sort,
}
trait Gallery {
fn store(artwork: Artwork) -> Result<(), ()>;
fn search(filter: Filter, sort: Sort) -> Result<(), ()>;
}
struct MockGallery {}
impl Gallery for MockGallery {
fn store(_artwork: Artwork) -> Result<(), ()> {
Ok(())
}
fn search(_search: Filter, _sort: Sort) -> Result<(), ()> {
Ok(())
}
}
struct Job {}
fn add_two(a: usize, b: usize) -> usize {
a + b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn add() {
assert_eq!(4, add_two(2, 2));
}
#[test]
fn dollars() {
let product = Product {
artwork: Artwork {
tags: HashSet::new(),
category: vec![],
name: "".into(),
description: "".into(),
},
cents: 1000,
quantity: 0,
featured: false,
};
assert_eq!(10.00, product.dollars());
let product = Product {
artwork: Artwork {
tags: HashSet::new(),
category: vec![],
name: "".into(),
description: "".into(),
},
cents: 1234,
quantity: 0,
featured: false,
};
assert_eq!(12.34, product.dollars());
}
#[test]
fn price_check() {
let artwork = Artwork {
tags: HashSet::new(),
category: vec![],
name: "".into(),
description: "".into(),
};
let product1 = Product {
artwork: artwork.clone(),
cents: 1000,
quantity: 0,
featured: false,
};
let mut product2 = Product {
artwork,
cents: 1000,
quantity: 0,
featured: false,
};
assert_eq!(product1, product2);
product2.cents = 1234;
assert_ne!(product1, product2);
assert!(product1 < product2);
}
}