Skip to content

Instantly share code, notes, and snippets.

@eterps
Last active October 22, 2018 08:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eterps/b76179de9953d502351a98c1afdbd4c8 to your computer and use it in GitHub Desktop.
Save eterps/b76179de9953d502351a98c1afdbd4c8 to your computer and use it in GitHub Desktop.
#![allow(dead_code)]
#![allow(unused)]
fn main() {
let add1 = |x| x + 1; // signature is: fn(T) -> T
let add = |x, y| x + y; // signature is: fn(T, T) -> T
println!("{}", add1(2));
println!("{}", add(2, 3));
// === 79. Modeling Simple Values: ===
pub struct CustomerId(i32);
pub struct OrderId(i32);
pub enum CustomerId2 { CustomerId2(i32) } // alternative
let customer_id = CustomerId(42);
let order_id = OrderId(42);
// binary operation `==` cannot be applied to type `main::CustomerId`
// note: an implementation of `std::cmp::PartialEq` might be missing for `main::CustomerId`
/*
if customer_id == order_id {
println!("Equal!")
}
*/
// Working with wrapper types:
let CustomerId(inner_value) = customer_id; // deconstruct / unwrap
println!("{}", inner_value);
// CustomerId -> ()
let process_customer_id = |CustomerId(inner_value)| println!("inner_value is {}", inner_value);
process_customer_id(customer_id);
// === 79. Modeling Complex Data: ===
enum Never {}
type CustomerInfo = Never;
type ShippingAddress = Never;
type BillingAddress = Never;
type OrderLine = Never;
struct Order {
customer_info: CustomerInfo,
shipping_address: ShippingAddress,
billing_address: BillingAddress,
order_lines: Vec<OrderLine>,
}
// === 84. Modeling with Choice Types: ===
#[derive(PartialEq, Debug)]
pub struct WidgetCode(String);
type GizmoCode = Never;
enum ProductCode {
Widget(WidgetCode),
Gizmo(GizmoCode),
}
// === 85. Modeling Workflows with Functions: ===
type UnvalidatedOrder = Never;
type ValidatedOrder = Never;
type ValidateOrder = fn(UnvalidatedOrder) -> ValidatedOrder;
fn validate_order(_: UnvalidatedOrder) -> ValidatedOrder { unimplemented!() }
// type Diameter = f64;
// fn circle(_: Diameter) -> Picture { unimplemented!() }
// -- workflow has an outputA *and* an outputB:
type AcknowledgementSent = Never;
type OrderPlaced = Never;
type BillableOrderPlaced = Never;
struct PlaceOrderEvents {
acknowledgement_sent: AcknowledgementSent,
order_placed: OrderPlaced,
billable_order_placed: BillableOrderPlaced,
}
type PlaceOrder = fn(UnvalidatedOrder) -> PlaceOrderEvents;
// -- workflow has an outputA *or* an outputB:
type QuoteForm = Never;
type OrderForm = Never;
pub struct EnvelopeContents(String);
enum CategorizedMail {
Quote(QuoteForm),
Order(OrderForm),
}
type CategorizeInboundMail = fn(EnvelopeContents) -> CategorizedMail;
// -- workflow has an inputA *or* an inputB:
// create a choice type and pass it as a parameter
// -- workflow has an inputA *and* an inputB:
// choice 1, pass each input as a separate parameter:
type ProductCatalog = Never;
type PricedOrder = Never;
type CalculatePrices = fn(OrderForm, ProductCatalog) -> PricedOrder;
// ProductCatalog is a dependency rather than a real input, so this is the preferred approach here
// this also lets us use dependency injection
// choice 2, create a record type to contain them both:
struct CalculatePricesInput {
order_form: OrderForm,
product_catalog: ProductCatalog,
}
type CalculatePrices2 = fn(CalculatePricesInput) -> PricedOrder;
// If both inputs are always required and strongly connected to each other
// this is the preferred approach (in some situations you can use tuples instead)
// === 87. Documenting Effects in the Function Signature: ===
type ValidatedOrder2 = fn(UnvalidatedOrder) -> Result<ValidatedOrder, Vec<ValidationError>>;
struct ValidationError {
field_name: String,
error_description: String,
}
//type ValidatedOrder3 = fn(UnvalidatedOrder) -> Async<Result<ValidatedOrder, Vec<ValidationError>>>;
//type ValidationResponse<T> = Future<Item = T, Error = ValidationError>;
// === 5.6 A Question of Identity: Value Objects ===
let widget_code1 = WidgetCode(String::from("W1234"));
let widget_code2 = WidgetCode(String::from("W1234"));
println!("{:?}", widget_code1 == widget_code2); // prints "true"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment