Code Identifier
- Краен срок:
- 25.10.2018 17:00
- Точки:
- 20
Срокът за предаване на решения е отминал
Задачата е да напишете тип, който "обвива" програмен идентификатор. Примерно, имена на променливи. Различните езици си имат различни стилове за идентификация, някои се очаква да са under_scored
, някои ще са camelCased
, тук-таме лиспаджиите kebab-case
-ват неща. Ние ще очакваме да започнете от стандартния rust-ки стил за идентификатор: underscored, и да генерирате всички други. Примерно:
let code_identifier = CodeIdentifier::new("some_var").unwrap();
code_identifier.camelcase() // => "someVar"
code_identifier.underscore() // => "some_var"
Забележете, че new
функцията приема &str
, но спокойно можете да си алокирате String
от този &str
чрез String::from
и да боравите с него (или можете да си съхраните нещо друго? Както решите.)
Валидност
Очакваме да проверите, че подаденото наистина е валиден идентификатор, по следните правила:
- Първия символ трябва да е задължително буква.
- Всеки следващ символ може да е буква, цифра, или
_
.
Тоест, това са валидни идентификатори: some_var
, abc1
.
Невалидни идентификатори са, например 1abc
, @@@
.
Дефинираме "буква" като: това, за което char::is_alphabetic
върне истина.
Дефинираме "цифра" като: това, за което char::is_numeric
върне истина.
Нормализация на входа
Ако ви подадем низ с интервали, табове, или нови редове преди или след идентификатора, изчистете ги. Тоест, тези две са еквивалентни:
let code_identifier = CodeIdentifier::new(" some_var ");
let code_identifier = CodeIdentifier::new("some_var");
Ако ви подадем вход с разнообразен casing (големи/малки букви), нормализирайте го:
let code_identifier = CodeIdentifier::new("SoMe_vAr").unwrap();
code_identifier.underscore() // => "some_var"
code_identifier.screaming_snakecase() // => "SOME_VAR"
code_identifier.camelcase() // => "someVar"
Специални случаи
Случаи, за които (за нещастие) не сме се сетили, съответно няма да имаме тестове за тях:
- Няколко
_
символа един след друг - Символ
_
в края на идентификатора
Можете да се справите с тези случаи както решите, или да ги игнорирате.
Ето структурата на кода, която очакваме:
/// Необходимо е CodeIdentifier да имплементира Debug, за да можем да го
/// използваме в тестови assertion-и.
///
#[derive(Debug)]
pub struct CodeIdentifier {
// Каквито полета ви трябват
}
impl CodeIdentifier {
/// Функцията ще върне Option<CodeIdentifier>, което ще бъде:
/// - None: ако входа не е валиден идентификатор. Вижте горе за това
/// какво значи "валиден идентификатор".
/// - Some(code_identifier): Ако входа е валиден.
///
pub fn new(identifier: &str) -> Option<Self> {
unimplemented!()
}
/// Конвертира идентификатора до camelcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "someVar"
///
pub fn camelcase(&self) -> String {
unimplemented!()
}
/// Конвертира идентификатора до titlecased вариант (camelcased с първа заглавна буква).
/// - Примерен вход: "some_var"
/// - Примерен изход: "SomeVar"
///
pub fn titlecase(&self) -> String {
unimplemented!()
}
/// Конвертира идентификатора до kebabcased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some-var"
///
pub fn kebabcase(&self) -> String {
unimplemented!()
}
/// Конвертира идентификатора до underscored вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "some_var"
///
/// - Примерен вход: "Some_Var"
/// - Примерен изход: "some_var"
///
pub fn underscore(&self) -> String {
unimplemented!()
}
/// Конвертира идентификатора до screaming-snakecased вариант.
/// - Примерен вход: "some_var"
/// - Примерен изход: "SOME_VAR"
///
pub fn screaming_snakecase(&self) -> String {
unimplemented!()
}
}
Внимавайте всички типове и методи, които ни трябват, да бъдат маркирани като pub
, за да могат тестовете ни да ги викат. Прочетете и общия guide за писане на домашни.
Задължително прочетете (или си припомнете): Указания за предаване на домашни