Checking Parts of Strings

I've converted a Python script into Rust, and it is working the same, but wonder if this is a proper way to splice and check strings?

The 2 "if" statements is the code in question.

Python Code:

            if k[:3] == "'''" and doc_switch == False or k[:3] == '"""' and doc_switch == False:
                if "'''" in k[3:] or '"""' in k[3:]:
                    not_code_lines += 1
                    only_comments += 1
                    continue
                else:
                    doc_switch = True

Converted to Rust code:

if k.get(..3) == Some("'''") && doc_switch == false || k.get(..3) == Some("\"\"\"") &&
                doc_switch == false {

                if k.get(3..).unwrap().to_string().contains("'''") ||
                    k.get(3..).unwrap().to_string().contains("\"\"\"") {
                    not_code_lines += 1;
                    only_comments += 1;
                    continue;
                }
                else {
                    doc_switch = true;
                }
            }

If you would like to see the full scripts their on my repository: https://github.com/Bren3232/Count-Lines

  1. You don't need to to_string() in order to .contains().
  2. The Python code raises an exception when the string is too short, so the Rust code is not completely equivalent.
1 Like

Instead of slicing and specifying lengths manually, you are probably looking for more evocative helper methods such as starts_with() and ends_with().

1 Like

I don't think so, if the string is too short it will gives you the whole string

The above suggestions are true and useful, except the python code does work on short strings.
Thanks.

So if the string is '''""", then not_code_lines += 1 and only_comments += 1? I'm not sure this is intended behaviour.

If it's not, you should consider matching against a regexp '''.*?''' and """.*?""".

1 Like

:+1: to this. The regex crate is incredibly fast, so if you're doing string processing, you should probably just default to using it unless you have strong reasons to do something else. As a bonus, you're more likely to handle Unicode properly that way too.

1 Like

Without going into the algorithm or anything like that...

You can uses matches! to remove some redundancy.

if doc_switch == false && matches!(k.get(..3), Some("'''") | Some("\"\"\""))

get followed by unwrap is pretty much just indexing.

    let rest = &k[3..];
    if rest.contains("'''") || rest.contains("\"\"\"") {
2 Likes