fn parse_record(record: &str) -> Result<Record, ParseError> {
    // We use ".split" on ',' to create a vector of strings.
    // This vector will contain elements of each field in the record
    // without the delimiting commas separating them.
    let fields: Vec<&str> = record.split(',').collect();

    // The id and name fields are required, so a match expression is used
    // in order to extract the data (if possible) and place it into the
    // appropriate variables.

    // Here we try to get the "id" portion of the record, which should be
    // the first entry (which is index 0). We then use "from_str_radix"
    // to parse the string id into a numeric i64 id. We abort the function
    // if this conversion fails, or if we do not find the id.
    let id = match fields.get(0) {
        Some(id) => i64::from_str_radix(id, 10)?,
        None => return Err(ParseError::EmptyRecord),
    };

    // Here we try to get the "name" portion of the record, which should
    // be the second entry (which is index 1). We also ensure that a name
    // actually exists by using filter on the name and seeing if it is an
    // empty string (""). The "fields" vector contains &str type, "get"
    // references again (&&str) and then filter references a third time (&&&str).
    // The asterisks (**) remove two of these references so we can compare
    // to the empty string ("") which is a &str. This is not something to
    // worry about because the compiler will tell you if asterisks are needed
    // when you attempt to compile the program.
    let name = match fields.get(1).filter(|name| **name != "") {
        Some(name) => name.to_string(),
        None => return Err(ParseError::MissingField("name".to_owned())),
    };

    // The email field is the third piece of data (index 2). "Get" returns
    // an Option, so all we need to do is simply map the email to a
    // String type with "to_string" and then filter if it is empty.
    // Map and filter will only run if we actually have data to work
    // with, since emails are optional.
    let email = fields
        .get(2)
        .map(|email| email.to_string())
        .filter(|email| email != "");

    Ok(Record { id, name, email })
}
/// Parses a single record line.
Parses a single record line.
Parses a single record line .
fn parse_record(record: &str) -> Result<Record, ParseError> {
    // We use ".split" on ',' to create a vector of strings.
    // This vector will contain elements of each field in the record
    // without the delimiting commas separating them.
    let fields: Vec<&str> = record.split(',').collect();
    // The id and name fields are required, so a match expression is used
    // in order to extract the data (if possible) and place it into the
    // appropriate variables.
    // Here we try to get the "id" portion of the record, which should be
    // the first entry (which is index 0). We then use "from_str_radix"
    // to parse the string id into a numeric i64 id. We abort the function
    // if this conversion fails, or if we do not find the id.
    let id = match fields.get(0) {
        Some(id) => i64::from_str_radix(id, 10)?,
        None => return Err(ParseError::EmptyRecord),
    };
    // Here we try to get the "name" portion of the record, which should
    // be the second entry (which is index 1). We also ensure that a name
    // actually exists by using filter on the name and seeing if it is an
    // empty string (""). The "fields" vector contains &str type, "get"
    // references again (&&str) and then filter references a third time (&&&str).
    // The asterisks (**) remove two of these references so we can compare
    // to the empty string ("") which is a &str. This is not something to
    // worry about because the compiler will tell you if asterisks are needed
    // when you attempt to compile the program.
    let name = match fields.get(1).filter(|name| **name != "") {
        Some(name) => name.to_string(),
        None => return Err(ParseError::MissingField("name".to_owned())),
    };
    // The email field is the third piece of data (index 2). "Get" returns
    // an Option, so all we need to do is simply map the email to a
    // String type with "to_string" and then filter if it is empty.
    // Map and filter will only run if we actually have data to work
    // with, since emails are optional.
    let email = fields
        .get(2)
        .map(|email| email.to_string())
        .filter(|email| email != "");
    Ok(Record { id, name, email })
}
fn parse_record ( record : & str ) -> Result < Record , ParseError > { // We use ".split" on ',' to create a vector of strings. // This vector will contain elements of each field in the record // without the delimiting commas separating them. let fields : Vec < & str > = record . split ( ',' ) . collect ( ) ; // The id and name fields are required, so a match expression is used // in order to extract the data (if possible) and place it into the // appropriate variables. // Here we try to get the "id" portion of the record, which should be // the first entry (which is index 0). We then use "from_str_radix" // to parse the string id into a numeric i64 id. We abort the function // if this conversion fails, or if we do not find the id. let id = match fields . get ( 0 ) { Some ( id ) => i64 :: from_str_radix ( id , 10 ) ? , None => return Err ( ParseError :: EmptyRecord ) , } ; // Here we try to get the "name" portion of the record, which should // be the second entry (which is index 1). We also ensure that a name // actually exists by using filter on the name and seeing if it is an // empty string (""). The "fields" vector contains &str type, "get" // references again (&&str) and then filter references a third time (&&&str). // The asterisks (**) remove two of these references so we can compare // to the empty string ("") which is a &str. This is not something to // worry about because the compiler will tell you if asterisks are needed // when you attempt to compile the program. let name = match fields . get ( 1 ) . filter ( | name | * * name != " " ) { Some ( name ) => name . to_string ( ) , None => return Err ( ParseError :: MissingField ( " " . to_owned ( ) ) ) , } ; // The email field is the third piece of data (index 2). "Get" returns // an Option, so all we need to do is simply map the email to a // String type with "to_string" and then filter if it is empty. // Map and filter will only run if we actually have data to work // with, since emails are optional. let email = fields . get ( 2 ) . map ( | email | email . to_string ( ) ) . filter ( | email | email != " " ) ; Ok ( Record { id , name , email } ) }
Parses a single record line.
Parses a single record line .
record
&str