aboutsummaryrefslogtreecommitdiff
path: root/helix-core/src/register.rs
blob: b39e4034efb71e300d4d953ceda7a20d38757e0d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
use std::collections::HashMap;

#[derive(Debug)]
pub struct Register {
    name: char,
    values: Vec<String>,
}

impl Register {
    pub const fn new(name: char) -> Self {
        Self {
            name,
            values: Vec::new(),
        }
    }

    pub fn new_with_values(name: char, values: Vec<String>) -> Self {
        if name == '_' {
            Self::new(name)
        } else {
            Self { name, values }
        }
    }

    pub const fn name(&self) -> char {
        self.name
    }

    pub fn read(&self) -> &[String] {
        &self.values
    }

    pub fn write(&mut self, values: Vec<String>) {
        if self.name != '_' {
            self.values = values;
        }
    }

    pub fn push(&mut self, value: String) {
        if self.name != '_' {
            self.values.push(value);
        }
    }
}

/// Currently just wraps a `HashMap` of `Register`s
#[derive(Debug, Default)]
pub struct Registers {
    inner: HashMap<char, Register>,
}

impl Registers {
    pub fn get(&self, name: char) -> Option<&Register> {
        self.inner.get(&name)
    }

    pub fn get_mut(&mut self, name: char) -> &mut Register {
        self.inner
            .entry(name)
            .or_insert_with(|| Register::new(name))
    }

    pub fn write(&mut self, name: char, values: Vec<String>) {
        self.inner
            .insert(name, Register::new_with_values(name, values));
    }

    pub fn read(&self, name: char) -> Option<&[String]> {
        self.get(name).map(|reg| reg.read())
    }

    pub fn inner(&self) -> &HashMap<char, Register> {
        &self.inner
    }
}