fn consume_package_name)>()

in util/label/label.rs [105:178]


fn consume_package_name<'s>(input: &'s str, label: &'s str) -> Result<(&'s str, Option<&'s str>)> {
    let is_absolute = match input.rfind("//") {
        None => false,
        Some(0) => true,
        Some(_) => {
            return Err(LabelError(err(
                label,
                "'//' cannot appear in the middle of the label.",
            )));
        }
    };

    let (package_name, rest) = match (is_absolute, input.find(':')) {
        (false, colon_pos) if colon_pos.map_or(true, |pos| pos != 0) => {
            return Err(LabelError(err(
                label,
                "relative packages are not permitted.",
            )));
        }
        (_, colon_pos) => {
            let (input, colon_pos) = if is_absolute {
                (&input[2..], colon_pos.map(|cp| cp - 2))
            } else {
                (input, colon_pos)
            };
            match colon_pos {
                Some(colon_pos) => (&input[0..colon_pos], &input[colon_pos..]),
                None => (input, ""),
            }
        }
    };

    if package_name.is_empty() {
        return Ok((rest, None));
    }

    if !package_name.chars().all(|c| {
        c.is_ascii_alphanumeric()
            || c == '/'
            || c == '-'
            || c == '.'
            || c == ' '
            || c == '$'
            || c == '('
            || c == ')'
            || c == '_'
    }) {
        return Err(LabelError(err(
            label,
            "package names may contain only A-Z, \
        a-z, 0-9, '/', '-', '.', ' ', '$', '(', ')' and '_'.",
        )));
    }
    if package_name.ends_with('/') {
        return Err(LabelError(err(
            label,
            "package names may not end with '/'.",
        )));
    }

    if rest.is_empty() && is_absolute {
        // This label doesn't contain the target name, we have to use
        // last segment of the package name as target name.
        return Ok((
            match package_name.rfind('/') {
                Some(pos) => &package_name[pos..],
                None => package_name,
            },
            Some(package_name),
        ));
    }

    Ok((rest, Some(package_name)))
}