Skip to content

Instantly share code, notes, and snippets.

@spdrman
Last active February 19, 2022 05:02
Show Gist options
  • Save spdrman/c3b716421ab83bea50447a20e46dd8ce to your computer and use it in GitHub Desktop.
Save spdrman/c3b716421ab83bea50447a20e46dd8ce to your computer and use it in GitHub Desktop.
Rust Ownership / Borrowing / Error handling
// Transfering ownership of a var to a function, and then back to main()
fn main() {
let mut array_main: [Vec<u8>; 3] = [vec![1], vec![2, 4], vec![]];
print(&mut array_main); //pass as mutable reference to array_main
println!("{:?}", array_main);
}
fn print(array: &mut [Vec<u8>; 3]) -> &[Vec<u8>; 3] {
for e in array.iter() {
println!("{:?}", e)
}
*array = [vec![2], vec![3, 5], vec![]]; // take ownership / borrow & change array_main
array // pass ownership back to main()
}
// STRINGS in RUST
// https://stackoverflow.com/questions/24158114/what-are-the-differences-between-rusts-string-and-str
// https://medium.com/@alisomay/strings-in-rust-28c08a2d3130
// Strings can be modified and enlarged (read+write) -- Str / &Str are like fixed sized arrays (read-only)
// ERROR handling in RUST
// https://stackoverflow.com/questions/57794849/result-getting-unexpected-type-argument
// https://nick.groenen.me/posts/rust-error-handling/
// https://dmerej.info/blog/post/killing-unwrap/
/*
thiserror is a great helper if you want to build meaningful error types
- I would highly recommend it to write errors you want to handle.
anyhow is useful if you don't particularly care what kind of error it is
- very handy when you simply want to handle "any" error.
For a binary, I would generally start any API with anyhow, until you need to differentiate between errors
- then create your new error type from thiserror::Error, swap our Result<T, anyhow::Error> with your error,
and handle it appropriately upstream.
For a library, I would create a general Error type for my whole library and return Result<T, crate::Error> everywhere;
adding in #[from] T conversions whenever I need to bubble up a new error type.
Then specialize as needed, ie an IoError.
*/
// Use Result<T, Box<dyn Error>> when not sure what error type to use
pub fn from_config(filename: &str) -> io::Result<Self> {
let file = File::open(filename)?;
// This has no error possibility -- returns a Result<T, E> where E is module specific
let args: Vec<String> = read_config(file);
// Pull out all errors and convert to type std::io::ErrorKind::NotFound
let params: Option<(String, String, String, String)> = args.drain(0..4).tuples().next();
params.ok_or(std::io::Error::new(std::io::ErrorKind::NotFound, "Could not read values into struct")).map(|(a, b, c, d)| BasicExample::new(a,b,c,d))
}
/// #[derive(Debug, Deserialize, Eq, PartialEq)]
/// struct Row {
/// city: String,
/// country: String,
/// #[serde(rename = "popcount")]
/// population: u64,
/// }
///
/// # fn main() { example().unwrap(); }
/// fn example() -> Result<(), Box<dyn Error>> {
/// let data = "\
/// city,country,popcount
/// Boston,United States,4628910
/// ";
/// let rdr = Reader::from_reader(data.as_bytes());
/// let mut iter = rdr.into_deserialize();
///
/// if let Some(result) = iter.next() {
/// let record: Row = result?;
/// assert_eq!(record, Row {
/// city: "Boston".to_string(),
/// country: "United States".to_string(),
/// population: 4628910,
/// });
/// Ok(())
/// } else {
/// Err(From::from("expected at least one record but got none"))
/// }
/// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment