fn ensure_correct_unique_name()

in crates/zbus_names/src/unique_name.rs [165:224]


fn ensure_correct_unique_name(name: &str) -> Result<()> {
    // Rules
    //
    // * Only ASCII alphanumeric, `_` or '-'
    // * Must begin with a `:`.
    // * Must contain at least one `.`.
    // * <= 255 characters.
    if name.is_empty() {
        return Err(Error::InvalidUniqueName(String::from(
            "must contain at least 4 characters",
        )));
    } else if name.len() > 255 {
        return Err(Error::InvalidUniqueName(format!(
            "`{}` is {} characters long, which is longer than maximum allowed (255)",
            name,
            name.len(),
        )));
    } else if name == "org.freedesktop.DBus" {
        // Bus itself uses its well-known name as its unique name.
        return Ok(());
    }
    // TODO: this is a hack to prevent panics when a message is received
    // where the sender is IBus.
    else if name == "org.freedesktop.IBus" {
        return Ok(());
    }

    // SAFETY: Just checked above that we've at least 1 character.
    let mut chars = name.chars();
    let mut prev = match chars.next().expect("no first char") {
        first @ ':' => first,
        _ => {
            // println!("WARNING: Invalid unique name detected: {}", name);
            return Err(Error::InvalidUniqueName(format!("must start with a `:` | {name}",)));
        },
    };

    let mut no_dot = true;
    for c in chars {
        if c == '.' {
            if prev == '.' {
                return Err(Error::InvalidUniqueName(String::from("must not contain a double `.`")));
            }

            if no_dot {
                no_dot = false;
            }
        } else if !c.is_ascii_alphanumeric() && c != '_' && c != '-' {
            return Err(Error::InvalidUniqueName(format!("`{c}` character not allowed")));
        }

        prev = c;
    }

    if no_dot {
        return Err(Error::InvalidUniqueName(String::from("must contain at least 1 `.`")));
    }

    Ok(())
}