cat_q/
lib.rs

1use std::collections::VecDeque;
2
3pub trait Scoring {
4    fn score(&self, normative: bool) -> u8;
5}
6
7pub enum Answer {
8   NeitherAgreeNorDisagree,
9   StronglyDisagree,
10   SomeWhatDisagree,
11   SomeWhatAgree,
12   StronglyAgree,
13   Disagree,
14   Agree,
15}
16
17pub enum Subscale {
18    Assimilation,
19    Compensation,
20    Masking,
21}
22
23impl Scoring for Answer {
24    fn score(&self, normative: bool) -> u8 {
25        if normative {
26            match self {
27                Self::NeitherAgreeNorDisagree => 4,
28                Self::SomeWhatDisagree => 5,
29                Self::StronglyDisagree => 7,
30                Self::SomeWhatAgree => 3,
31                Self::StronglyAgree => 1,
32                Self::Disagree => 6,
33                Self::Agree => 2,
34            } 
35        } else {
36            match self {
37                Self::NeitherAgreeNorDisagree => 4,
38                Self::SomeWhatDisagree => 3,
39                Self::StronglyDisagree => 1,
40                Self::SomeWhatAgree => 5,
41                Self::StronglyAgree => 7,
42                Self::Disagree => 2,
43                Self::Agree => 6,
44            }
45        }
46    }
47}
48
49#[derive(Debug)]
50pub struct FinalScore {
51    pub compensation_subtotal: u8,
52    pub assimilation_subtotal: u8,
53    pub masking_subtotal: u8,
54    pub total: u8,
55}
56
57pub struct Question {
58    score: Option<Answer>,
59    pub content: String,
60    subscale: Subscale,
61    normative: bool,
62}
63
64impl Question {
65    fn new(content: impl Into<String>, normative: bool, subscale: Subscale) -> Self {
66        Self {
67            content: content.into(),
68            score: None,
69            normative,
70            subscale,
71        }
72    }
73
74    pub fn answer(&mut self, answer: Answer) {
75        self.score = Some(answer)
76    }
77}
78
79pub struct CatQ {
80    questions: VecDeque<Question>,
81}
82
83impl CatQ {
84    pub fn new() -> Self {
85        let questions = vec![
86            Question::new("I have spent time learning social skills from television shows and films, and try to use these in my interactions", false, Subscale::Compensation),
87            Question::new("I learn how people use their bodies and faces to interact by watching television or fils, or by reading fiction", false, Subscale::Compensation),
88            Question::new("I monitor my body language or facial expressions so that I appear interested by the person I am interacting with", false, Subscale::Masking),
89            Question::new("I adjust my body language or facial expressions so that I appear interested by the person I am interacting with", false, Subscale::Masking),
90            Question::new("In my own social interactions, I use behaviors that I have learned from watching other people interacting", false, Subscale::Compensation),
91            Question::new("When I am interacting with someone, I deliberately copy their body language or facial expressions", false, Subscale::Compensation),
92            Question::new("I will repeat phrases that I have heard others say in the exact same way that I first heard them", false, Subscale::Compensation),
93            Question::new("I have researched the rules of social interactions to improve my own social skills", false, Subscale::Compensation),
94            Question::new("I have tried to improve my understanding of social skills by watching other people", false, Subscale::Compensation),
95            Question::new("I rarely feel the need to put on an act in order to get through a social situation", true, Subscale::Assimilation),
96            Question::new("I practice my facial expressions and body language to make sure they look natural", false, Subscale::Compensation),
97            Question::new("When in social situations, I try to find ways to avoid interacting with others", false, Subscale::Assimilation),
98            Question::new("I have to force myself to interact with people when I am in social situations", false, Subscale::Assimilation),
99            Question::new("In social situations, I feel like I'm 'performing' rather than being myself", false, Subscale::Assimilation),
100            Question::new("In social interactions, I do not pay attention to what my face or body are doing", true, Subscale::Masking),
101            Question::new("When talking to other people, I feel like the conversation flows naturally", true, Subscale::Assimilation),
102            Question::new("I don't feel the need to make eye contact with other people if I don't want to", true, Subscale::Masking),
103            Question::new("I monitor my body language or facial expressions so that I appear relaxed", false, Subscale::Masking),
104            Question::new("I adjust my body language or facial expressions so that I appear relaxed", false, Subscale::Masking),
105            Question::new("In social situations, I feel like I am pretending to be 'normal'", false, Subscale::Assimilation),
106            Question::new("I need the support of other people in order to socialize", false, Subscale::Assimilation),
107            Question::new("I have developed a script to follow in social situations", false, Subscale::Compensation),
108            Question::new("I am always aware of the impression I make on other people", false, Subscale::Masking),
109            Question::new("I always think about the impression I make on other people", false, Subscale::Masking),
110            Question::new("I feel free to be myself when I am with other people", true, Subscale::Assimilation),
111        ];
112
113        assert_eq!(questions.len(), 25);
114
115        let dec = VecDeque::from(questions);
116
117        Self {
118            questions: dec,
119        }
120    }
121
122    pub fn score(questions: Vec<Question>) -> FinalScore {
123        let mut final_score = FinalScore {
124            assimilation_subtotal: 0,
125            compensation_subtotal: 0,
126            masking_subtotal: 0,
127            total: 0,
128        };
129
130        final_score.total = questions.iter().fold(0 as u8, |attr, a| {
131            attr + match &a.score {
132                Some(x) => {
133                    let score = x.score(a.normative);
134
135                    match a.subscale {
136                        Subscale::Compensation => final_score.compensation_subtotal += score,
137                        Subscale::Assimilation => final_score.assimilation_subtotal += score,
138                        Subscale::Masking => final_score.masking_subtotal += score,
139                    }
140
141                    score
142                }
143                None => 0,
144            }
145        });
146
147        final_score
148    }
149
150    pub fn push_front(&mut self, question: Question) {
151        self.questions.push_front(question)
152    }
153
154    pub fn push_back(&mut self, question: Question) {
155        self.questions.push_back(question)
156    }
157
158    #[deprecated]
159    // use 'CatQ::push_front' instead
160    pub fn reádd_front(&mut self, question: Question) {
161        self.questions.push_front(question)
162    }
163
164    #[deprecated]
165    // use 'CatQ::push_back' instead
166    pub fn reádd_back(&mut self, question: Question) {
167        self.questions.push_back(question)
168    }
169}
170
171impl Iterator for CatQ {
172    type Item = Question;
173
174    fn next(&mut self) -> Option<Self::Item> {
175        self.questions.pop_front()
176    }
177}
178
179#[cfg(test)]
180mod tests {
181    use crate::CatQ;
182
183    #[test]
184    fn cat_q_twenty_five() {
185        CatQ::new();
186    }
187}