【Rust】ステートマシンによるメール判定【Algorithm】

fn isalphanum(c: char) -> bool {
    return c.is_alphabetic() || c.is_numeric();
}

fn isdot(c: char) -> bool {
    return c == '.';
}

fn isatmark(c: char) -> bool {
    return c == '@';
}

fn isend(c: char) -> bool {
    return c == '$';
}

fn isemail(mut s: String) -> bool {
    s += "$";

    let INIT = 0;
    let LOCAL_NOTDOT = 1;
    let LOCAL_DOT = 2;
    let ATMART = 3;
    let DOMAIN_NOTDOT = 4;
    let DOMAIN_DOT = 5;
    let OK = 6;
    let NG = 7;

    let mut state = INIT;

    for c in s.chars() {
        if state == INIT {
            if isalphanum(c) {
                state = LOCAL_NOTDOT;
            } else {
                state = NG;
                break;
            }
        } else if state == LOCAL_NOTDOT {
            if isalphanum(c) {
                state = LOCAL_NOTDOT;
            } else if isdot(c) {
                state = LOCAL_DOT;
            } else if isatmark(c) {
                state = ATMART;
            } else {
                state = NG;
                break;
            }
        } else if state == LOCAL_DOT {
            if isalphanum(c) {
                state = LOCAL_NOTDOT;
            } else {
                state = NG;
                break;
            }
        } else if state == ATMART {
            if isalphanum(c) {
                state = DOMAIN_NOTDOT;
            } else {
                state = NG;
                break;
            }
        } else if state == DOMAIN_NOTDOT {
            if isalphanum(c) {
                state = DOMAIN_NOTDOT;
            } else if isdot(c) {
                state = DOMAIN_DOT;
            } else if isend(c) {
                state = OK;
            } else {
                state = NG;
                break;
            }
        } else if state == DOMAIN_DOT {
            if isalphanum(c) {
                state = DOMAIN_NOTDOT;
            } else {
                state = NG;
                break;
            }
        } else if state == OK {
            break;
        } else if state == NG {
            break;
        } else {
            state = NG
        }
    }
    return state == OK;
}

fn main() {
    let email = "t@g.m".to_string();
    if isemail(email.clone()) {
        println!("メールアドレスです。{}", email);
    } else {
        println!("メールアドレスではありません。");
    }
}

Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.25s
Running `target/debug/basic`
メールアドレスです。t@g.m