fn main() {
// Option
// map, as_ref
// (owned) String
let payload: String = "colony".to_string();
// Wrap the String in an Option. This moves it, so payload is no more
let optw: Option<String> = Some(payload);
// in order to keep Option<String> alive and unmoved, as_ref will
// produce Option<&String> which will be sacrificed to map
let rf: Option<&String> = optw.as_ref();
// map converts Option<T> to Option<U> by applying fn to the wrapped value.
// if map would eat Option<String>, optw would be moved. In order to save
// optw, as_ref produces an Option<&String> for map to eat instead.
let opt_len: Option<usize> = rf.map(|payload| payload.len());
println!("map gets len, unwrapped: {:?}", opt_len.unwrap());
println!("while original is still alive, wrapped: {:?}", optw);
// std::option::Option::take
// fn take(&mut self) -> Option<T>
// Takes the value out of the option, leaving a None in its place.
let mut x = Some("thing".to_string());
let d: Option<String> = x.take();
assert_eq!(x, None);
println!("take(), unwrapped value: {:?}", d.unwrap());
// and
// alternate: return Option<U> if Option<T>::None
// fn and<U>(self, optb: Option<U>) -> Option<U>;
// mem::swap
let mut opt = Some(6_u8);
let mut nada: Option<u8> = None;
std::mem::swap(&mut nada, &mut opt);
println!("mem::swapped: {:?}", nada);
// mem::replace
let opt = Some(6_u8);
let mut nada: Option<u8> = None;
let res = std::mem::replace(&mut nada, opt);
println!("mem::replaced: {:?}", nada); // Some(6)
println!("mem::replaced, result: {:?}", res); // None
} // main