Решение на Code Identifier от Даяна Веселинова

Обратно към всички решения

Към профила на Даяна Веселинова

Резултати

  • 13 точки от тестове
  • 0 бонус точки
  • 13 точки общо
  • 10 успешни тест(а)
  • 5 неуспешни тест(а)

Код

/// Необходимо е CodeIdentifier да имплементира Debug, за да можем да го
/// използваме в тестови assertion-и.
///
#[derive(Debug)]
pub struct CodeIdentifier {
code_identifier: String,
}
impl CodeIdentifier {
/// Функцията ще върне Option<CodeIdentifier>, което ще бъде:
/// - None: ако входа не е валиден идентификатор. Вижте горе за това
/// какво значи "валиден идентификатор".
/// - Some(code_identifier): Ако входа е валиден.
///
pub fn new(identifier: &str) -> Option<Self> {
let initial=identifier.trim();
let first_char = identifier.trim().chars().next().unwrap();

.chars().next().unwrap() ще гръмне за празен низ :). Не сме тествали за това, така че е приемливо да се справиш както решиш с този case, но едва ли runtime panic е добро решение. За бъдещи домашни (и не само), мисли за такива специални случаи

if first_char.is_alphabetic() {
for c in initial.chars(){
if c.is_alphabetic() || c.is_numeric() || c=='_' {
continue;
}
else {
return None;
}
}
return Some(CodeIdentifier{code_identifier: identifier.to_string()});
}
return None;
}
/// Конвертира идентификатора до camelcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "someVar"
///
pub fn camelcase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string().to_lowercase();
if !initial.contains("_") {
return initial;
}
let size = initial.find("_").unwrap();
let first_part = &initial[0..size];
let mut result: String = first_part.to_string();
let mut last_string: &str = &initial;
let size_of = last_string.to_string().len();
last_string = &last_string[size+1..size_of];
while last_string.contains("_"){
let size = last_string.find("_").unwrap();
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..size];
let last_part=&last_string[size+1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
last_string = last_part;
}
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
result
}
/// Конвертира идентификатора до titlecased вариант (camelcased с първа заглавна буква).
/// - Примерен вход: "some_var"
/// - Примерен изход: "SomeVar"
///
pub fn titlecase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string().to_lowercase();
if !initial.contains("_") {
return initial;
}
let size = initial.find("_").unwrap();
let first_letter: &str=&initial[0..1].to_uppercase();
let first_part = &initial[1..size];
let mut result: String = first_letter.to_string();
result.push_str(first_part);
let mut last_string: &str = &initial;
let size_of = last_string.to_string().len();
last_string = &last_string[size+1..size_of];
while last_string.contains("_"){
let size = last_string.find("_").unwrap();
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..size];
let last_part=&last_string[size+1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
last_string = last_part;
}
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
result
}
/// Конвертира идентификатора до kebabcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some-var"
///
pub fn kebabcase(&self) -> String {
let initial = &self.code_identifier.trim();
if !initial.contains("_") {
return initial.to_string();
}
let result = str::replace(initial, "_", "-");
result.to_string()
}
/// Конвертира идентификатора до underscored вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some_var"
///
/// - Примерен вход: "Some_Var"
/// - Примерен изход: "some_var"
///
pub fn underscore(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string();
if !initial.contains("_") {
return initial;
}
let result: String = initial.to_lowercase();
result
}
/// Конвертира идентификатора до screaming-snakecased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "SOME_VAR"
///
pub fn screaming_snakecase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string();
if !initial.contains("_") {
return initial;
}
let result: String = initial.to_uppercase();
result
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20190123-22631-uqry87/solution)
    Finished dev [unoptimized + debuginfo] target(s) in 4.75s
     Running target/debug/deps/solution-2e785d603b538f71

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

     Running target/debug/deps/solution_test-29808948fb50ed3a

running 15 tests
test solution_test::test_both_static_and_dynamic_strings ... ok
test solution_test::test_camelcase_basic ... ok
test solution_test::test_cyrillic1 ... FAILED
test solution_test::test_digits1 ... ok
test solution_test::test_digits2 ... ok
test solution_test::test_digits3 ... FAILED
test solution_test::test_kebabcase_basic ... ok
test solution_test::test_multibyte_uppercase ... FAILED
test solution_test::test_normalize_case1 ... FAILED
test solution_test::test_normalize_case2 ... FAILED
test solution_test::test_screaming_snakecase_basic ... ok
test solution_test::test_titlecase_basic ... ok
test solution_test::test_underscore_basic ... ok
test solution_test::test_validity ... ok
test solution_test::test_whitespace ... ok

failures:

---- solution_test::test_cyrillic1 stdout ----
thread 'solution_test::test_cyrillic1' panicked at 'byte index 1 is not a char boundary; it is inside 'с' (bytes 0..2) of `стана`', libcore/str/mod.rs:2111:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

---- solution_test::test_digits3 stdout ----
thread 'solution_test::test_digits3' panicked at 'byte index 1 is not a char boundary; it is inside '٣' (bytes 0..2) of `٣_var`', libcore/str/mod.rs:2111:5

---- solution_test::test_multibyte_uppercase stdout ----
thread 'solution_test::test_multibyte_uppercase' panicked at 'byte index 1 is not a char boundary; it is inside 'ß' (bytes 0..2) of `ßpecial_case`', libcore/str/mod.rs:2111:5

---- solution_test::test_normalize_case1 stdout ----
thread 'solution_test::test_normalize_case1' panicked at 'assertion failed: `(left == right)`
  left: `"SomeVar"`,
 right: `"somevar"`', tests/solution_test.rs:72:5

---- solution_test::test_normalize_case2 stdout ----
thread 'solution_test::test_normalize_case2' panicked at 'assertion failed: `(left == right)`
  left: `"SomeVar"`,
 right: `"SOMEVAR"`', tests/solution_test.rs:84:5


failures:
    solution_test::test_cyrillic1
    solution_test::test_digits3
    solution_test::test_multibyte_uppercase
    solution_test::test_normalize_case1
    solution_test::test_normalize_case2

test result: FAILED. 10 passed; 5 failed; 0 ignored; 0 measured; 0 filtered out

error: test failed, to rerun pass '--test solution_test'

История (2 версии и 3 коментара)

Даяна качи първо решение на 24.10.2018 21:54 (преди над 4 години)

Даяна качи решение на 25.10.2018 10:18 (преди над 4 години)

/// Необходимо е CodeIdentifier да имплементира Debug, за да можем да го
/// използваме в тестови assertion-и.
///
#[derive(Debug)]
pub struct CodeIdentifier {
code_identifier: String,
}
impl CodeIdentifier {
/// Функцията ще върне Option<CodeIdentifier>, което ще бъде:
/// - None: ако входа не е валиден идентификатор. Вижте горе за това
/// какво значи "валиден идентификатор".
/// - Some(code_identifier): Ако входа е валиден.
///
pub fn new(identifier: &str) -> Option<Self> {
let initial=identifier.trim();
let first_char = identifier.trim().chars().next().unwrap();

.chars().next().unwrap() ще гръмне за празен низ :). Не сме тествали за това, така че е приемливо да се справиш както решиш с този case, но едва ли runtime panic е добро решение. За бъдещи домашни (и не само), мисли за такива специални случаи

if first_char.is_alphabetic() {
for c in initial.chars(){
- if 'a'<=c && 'z'>=c || 'A'<=c && 'Z'>=c || c.is_numeric() || c=='_' {
+ if c.is_alphabetic() || c.is_numeric() || c=='_' {
continue;
}
else {
return None;
}
}
return Some(CodeIdentifier{code_identifier: identifier.to_string()});
}
return None;
}
/// Конвертира идентификатора до camelcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "someVar"
///
pub fn camelcase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string().to_lowercase();
if !initial.contains("_") {
return initial;
}
let size = initial.find("_").unwrap();
let first_part = &initial[0..size];
let mut result: String = first_part.to_string();
let mut last_string: &str = &initial;
let size_of = last_string.to_string().len();
last_string = &last_string[size+1..size_of];
while last_string.contains("_"){
let size = last_string.find("_").unwrap();
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..size];
let last_part=&last_string[size+1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
last_string = last_part;
}
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
result
}
/// Конвертира идентификатора до titlecased вариант (camelcased с първа заглавна буква).
/// - Примерен вход: "some_var"
/// - Примерен изход: "SomeVar"
///
pub fn titlecase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string().to_lowercase();
if !initial.contains("_") {
return initial;
}
let size = initial.find("_").unwrap();
let first_letter: &str=&initial[0..1].to_uppercase();
let first_part = &initial[1..size];
let mut result: String = first_letter.to_string();
result.push_str(first_part);
let mut last_string: &str = &initial;
let size_of = last_string.to_string().len();
last_string = &last_string[size+1..size_of];
while last_string.contains("_"){
let size = last_string.find("_").unwrap();
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..size];
let last_part=&last_string[size+1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
last_string = last_part;
}
let first_part=&last_string[0..1].to_uppercase();
let second_part = &last_string[1..last_string.len()];
result.push_str(first_part);
result.push_str(second_part);
result
}
/// Конвертира идентификатора до kebabcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some-var"
///
pub fn kebabcase(&self) -> String {
let initial = &self.code_identifier.trim();
if !initial.contains("_") {
return initial.to_string();
}
let result = str::replace(initial, "_", "-");
result.to_string()
}
/// Конвертира идентификатора до underscored вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some_var"
///
/// - Примерен вход: "Some_Var"
/// - Примерен изход: "some_var"
///
pub fn underscore(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string();
if !initial.contains("_") {
return initial;
}
let result: String = initial.to_lowercase();
result
}
/// Конвертира идентификатора до screaming-snakecased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "SOME_VAR"
///
pub fn screaming_snakecase(&self) -> String {
let initial = &self.code_identifier;
let initial = initial.trim().to_string();
if !initial.contains("_") {
return initial;
}
let result: String = initial.to_uppercase();
result
}
}

Повечето грешки от тестовете идват от кирилица и друг unicode. Индексирането на низ е по байтове, а символите вътре може да са по два или повече байта. Когато напишеш нещо като index+1, това не е задължително да е следващия низ, а може да се падне по средата на буква, което е грешка.

Би могла да жонглираш дължини на символи ако използваш метода len_utf8: https://doc.rust-lang.org/std/primitive.char.html#method.len_utf8. Но ти препоръчвам просто да избягваш да правиш подобно индексиране. Доста по-лесно е да итерираш по char-ове. Разгледай останалите решения (примерно първото, което е моето) за идея как би се получило това.