Last active
October 22, 2018 08:28
-
-
Save eterps/b76179de9953d502351a98c1afdbd4c8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![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