Skip to content

Commit

Permalink
Replace excessive nesting with early exit
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoolean committed Nov 20, 2024
1 parent 4ae8a8e commit 6e3496d
Showing 1 changed file with 102 additions and 101 deletions.
203 changes: 102 additions & 101 deletions ufo2fontir/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -670,121 +670,122 @@ fn postscript_names(lib_plist: &plist::Dictionary) -> Result<PostscriptNames, Ba

/// https://unifiedfontobject.org/versions/ufo3/lib.plist/#publicopentypemeta
fn meta_records(lib_plist: &plist::Dictionary) -> Result<Vec<(Tag, Metadata)>, BadSource> {
// TODO: Use idiomatic error handling.
// TODO: Simplify.

const OPENTYPE_CATEGORIES: &str = "public.openTypeCategories";

// Registered tags that UFOv3 specifies but that are not in write-fonts
const APPL: Tag = Tag::new(b"appl");
const BILD: Tag = Tag::new(b"bild");

let property = lib_plist.get(OPENTYPE_CATEGORIES);
let Some(property) = lib_plist.get(OPENTYPE_CATEGORIES) else {
// Key was not present, use default:
return Ok(Default::default());
};

// TODO: Use idiomatic error handling.
// TODO: Simplify.
let Some(dictionary) = property.as_dictionary() else {
// Key is present but was not a dictionary, error.
return Err(BadSource::custom(
"lib.plist",
"public.postscriptNames must be a dictionary",
));
};

match property.map(plist::Value::as_dictionary) {
// Dictionary is present, interpret:
Some(Some(dictionary)) => dictionary
.iter()
.map(|(key, value)| {
// Parse each tag, and metadata as appropriate from tag.
let tag = Tag::new_checked(key.as_bytes()).map_err(|err| {
BadSource::custom(
"lib.plist",
format!("meta record has an invalid tag '{}': {}", key, err),
)
})?;

let metadata = match tag {
// "If present, [...] the registered tags dlng and slng have
// their values each stored as an array of ScriptLangTag
// strings"
DLNG | SLNG => Metadata::ScriptLangTags({
// Interpret and validate as a plist array:
let array = value.as_array().ok_or_else(|| {
BadSource::custom(
"lib.plist",
format!(
"meta {} record must contain an array of ScriptLangTag strings",
tag
),
)
})?;

// ...and as a plist array of strings
let strings = array
.iter()
.map(plist::Value::as_string)
.map(|value| {
value.ok_or_else(|| {
BadSource::custom(
"lib.plist",
format!(
"meta {} record array must only contain <string> values",
tag
),
)
})
})
.collect::<Result<Vec<_>, _>>()?;

// ...and as a plist array of ScriptLangTags
strings
.into_iter()
.map(|string| {
ScriptLangTag::new(string.into()).map_err(|err| {
BadSource::custom(
"lib.plist",
format!(
"meta {} record contains an invalid \
ScriptLangTag '{}': {}",
tag, string, err
),
)
})
// Dictionary is present, interpret.
dictionary
.iter()
.map(|(key, value)| {
// Parse each tag, and metadata as appropriate from tag.
let tag = Tag::new_checked(key.as_bytes()).map_err(|err| {
BadSource::custom(
"lib.plist",
format!("meta record has an invalid tag '{}': {}", key, err),
)
})?;

let metadata = match tag {
// "If present, [...] the registered tags dlng and slng have
// their values each stored as an array of ScriptLangTag
// strings"
DLNG | SLNG => Metadata::ScriptLangTags({
// Interpret and validate as a plist array:
let array = value.as_array().ok_or_else(|| {
BadSource::custom(
"lib.plist",
format!(
"meta {} record must contain an array of ScriptLangTag strings",
tag
),
)
})?;

// ...and as a plist array of strings
let strings = array
.iter()
.map(plist::Value::as_string)
.map(|value| {
value.ok_or_else(|| {
BadSource::custom(
"lib.plist",
format!(
"meta {} record array must only contain <string> values",
tag
),
)
})
.collect::<Result<_, _>>()?
}),
// "If present, the registered tags appl and bild have their
// values stored as data"
APPL | BILD => Metadata::Other(
value
.as_data()
.ok_or_else(|| {
})
.collect::<Result<Vec<_>, _>>()?;

// ...and as a plist array of ScriptLangTags
strings
.into_iter()
.map(|string| {
ScriptLangTag::new(string.into()).map_err(|err| {
BadSource::custom(
"lib.plist",
format!("meta table {} record must contain <data>", tag),
format!(
"meta {} record contains an invalid \
ScriptLangTag '{}': {}",
tag, string, err
),
)
})?
.to_vec(),
),
// "Any private tag must have its value stored as data or
// string"
_ => {
let other: Vec<u8> = match value {
plist::Value::Data(vec) => Ok(vec.to_owned()),
plist::Value::String(string) => Ok(string.as_bytes().to_vec()),
_ => Err(BadSource::custom(
})
})
.collect::<Result<_, _>>()?
}),
// "If present, the registered tags appl and bild have their
// values stored as data"
APPL | BILD => Metadata::Other(
value
.as_data()
.ok_or_else(|| {
BadSource::custom(
"lib.plist",
"Private meta table records must be <string> or <data>",
)),
}?;

Metadata::Other(other)
}
};

Ok((tag, metadata))
})
.collect(),
format!("meta table {} record must contain <data>", tag),
)
})?
.to_vec(),
),
// "Any private tag must have its value stored as data or
// string"
_ => {
let other: Vec<u8> = match value {
plist::Value::Data(vec) => Ok(vec.to_owned()),
plist::Value::String(string) => Ok(string.as_bytes().to_vec()),
_ => Err(BadSource::custom(
"lib.plist",
"Private meta table records must be <string> or <data>",
)),
}?;

Metadata::Other(other)
}
};

// Key is present but was not a dictionary, error:
Some(None) => Err(BadSource::custom(
"lib.plist",
"public.postscriptNames must be a dictionary",
)),
// Key was not present, use default:
None => Ok(Default::default()),
}
Ok((tag, metadata))
})
.collect()
}

fn units_per_em<'a>(font_infos: impl Iterator<Item = &'a norad::FontInfo>) -> Result<u16, Error> {
Expand Down

0 comments on commit 6e3496d

Please sign in to comment.