1#![feature(trace_macros)]
2#![feature(iter_advance_by)]
3#[macro_use]
4extern crate diesel;
5extern crate dotenv;
6
7pub mod attack;
8pub mod cipher;
9pub mod encoding;
11mod schema;
12
13#[macro_use]
14extern crate diesel_migrations;
15
16#[macro_use]
17extern crate error_chain;
18
19use crate::cipher::affine::WrongAffineKey;
20
21error_chain! {
23 types {
24 Error, ErrorKind, ResultExt, Result;
25 }
26 errors {
27 ConversionError(var: &'static str, var_type: &'static str, tried_type: &'static str) {
28 description("Conversion failed.")
29 display("{} type variable '{}' could not converted to {}", var_type, var, tried_type)
30 }
31 DatabaseError(message: String) {
32 description("Database error")
33 display("{}", message)
34 }
35 StringIndexError(searched_string: String, message: &'static str){
36 description("Error looking for a string.")
37 display("Error looking for {} text. Additional information: {}", searched_string, message)
38 }
39 IOError(file: String){
40 description("Error reading/writing file.")
41 display("Error reading/writing {} file.", file)
42 }
43 FolderError(folder: String){
44 description("Error creating folder.")
45 display("Error creating folder: {}", folder)
46 }
47 KeyError(key: String, message: String){
48 description("Error with given key.")
49 display("Problem with key {}:\n{}", key, message)
50 }
51 NotExistingLanguage(language_tried: String) {
52 description("You have tried to operate with a language that does not exist yet at database.")
53 display("Does not exist any dictionary for {} language", language_tried)
54 }
55 WrongAffineKeyError(wrong_key: WrongAffineKey){
56 description("You selected a wrong Affine key.")
57 display("{}", wrong_key)
58 }
59 WrongKeyLength(wrong_key: String, charset: String){
60 description("Wrong key used: Length is not the same than key one")
61 display("Key length is {} and charset length is {}", wrong_key.len(), charset.len())
62 }
63 WrongKeyRepeatedCharacters(wrong_key: String){
64 description("Wrong key used: Key uses repeated characters")
65 display("{}", wrong_key)
66 }
67 CharacterMappingError(wrong_char: String){
68 description("Error trying to substitute char.")
69 display("Char tried to substitute {}", wrong_char)
70 }
71 EmptyMapping {
72 description("Mapping has no more cipherletters.")
73 display("Empty mapping.")
74 }
75 NoMappingAvailable(word: String, dictionary: String){
76 description("No candidate mapping was found for word.")
77 display("Word was {} and tried dictionary was {}", word, dictionary)
78 }
79 }
80}
81
82pub trait FromStr<T> {
84 fn fromStr(s: T) -> Self;
86}
87
88impl FromStr<&str> for char {
89 fn fromStr(s: &str) -> Self {
90 s.chars().next().expect(format!("Could not create char from given string: {}", s).as_str())
91 }
92}
93
94pub trait FindFromIndex<T, U> {
96
97 fn findFromIndex(text: &T, text_to_find: U, index: usize) -> Option<usize>;
107}
108
109impl <U: AsRef<str>> FindFromIndex<String, U> for String {
110 fn findFromIndex(text: &String, text_to_find: U, index: usize) -> Option<usize> {
111 let mut text_iter = text.chars();
112 if let Ok(()) = text_iter.advance_by(index) {
113 let remaining_text: String = text_iter.collect();
114 match remaining_text.find(text_to_find.as_ref()) {
115 Some(current_index) => return Some(current_index + index),
116 None => None
117 }
118 } else {
119 None
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
129 fn test_find_from_index() {
130 let text = "This is a text where I want to find another text.".to_string();
131 let text_to_find = "text";
132 let expected_index: usize = 44;
133 if let Some(found_index) = String::findFromIndex(&text, text_to_find, 14) {
134 assert_eq!(found_index, expected_index);
135 } else {
136 assert!(false)
137 }
138 }
139
140}