@@ -14,7 +14,7 @@ namespace zest {
1414class SmartPort {
1515 public:
1616 /* *
17- * @brief Construct a Smart Port from its number
17+ * @brief Create a Smart Port using its number
1818 *
1919 * @note the smart port labelled "1" on the brain has a port number of 1
2020 *
@@ -26,7 +26,7 @@ class SmartPort {
2626 }
2727
2828 /* *
29- * @brief Construct a Smart Port from its index
29+ * @brief Create a Smart Port using its index
3030 *
3131 * @note the smart port labelled "1" on the brain has a port index of 0
3232 *
@@ -100,11 +100,23 @@ constexpr auto PORT_20 = SmartPort::from_number(20);
100100constexpr auto PORT_21 = SmartPort::from_number(21 );
101101} // namespace ports
102102
103+ /* *
104+ * @brief ADI Port class. Represents an ADI Port on a the brain or on a 3-wire expander.
105+ *
106+ * ADI Ports may be represented as a 0-indexed number, or a char (e.g 'a' or 'C'). This class
107+ * provides an interface so the developer doesn't have to worry about conversions.
108+ */
103109class AdiPort {
104110 public:
105- static constexpr AdiPort from_letter (char port) {
111+ /* *
112+ * @brief Create an ADI Port using its character
113+ *
114+ * @param port can be lowercase, uppercase, or even an index
115+ * @return constexpr AdiPort
116+ */
117+ static constexpr AdiPort from_char (char port) {
106118 // if the index is provided as a character
107- if (port >= ' 0' && port <= ' 9 ' ) {
119+ if (port >= ' 0' && port <= ' 8 ' ) {
108120 return AdiPort (port - ' 0' );
109121 }
110122 // convert to uppercase if needed
@@ -115,34 +127,65 @@ class AdiPort {
115127 return AdiPort (port - ' A' );
116128 }
117129
130+ /* *
131+ * @brief Create an ADI Port using its index
132+ *
133+ * @param index the port as an index (e.g 'A' has an index of 0)
134+ * @return constexpr AdiPort
135+ */
118136 static constexpr AdiPort from_index (uint8_t index) {
119137 return AdiPort (index);
120138 }
121139
122- constexpr char as_letter () const {
123- return m_index;
140+ /* *
141+ * @brief Get the ADI Port as a char
142+ *
143+ * @note the returned char will be uppercase
144+ *
145+ * @return constexpr char
146+ */
147+ constexpr char as_char () const {
148+ // convert index to an uppercase letter
149+ return m_index + ' A' ;
124150 }
125151
152+ /* *
153+ * @brief Get the ADI Port as an index
154+ *
155+ * @return constexpr uint8_t
156+ */
126157 constexpr uint8_t as_index () const {
127158 return m_index;
128159 }
129160
130161 private:
131- uint8_t m_index;
132-
133- constexpr AdiPort (uint8_t index)
162+ /* *
163+ * @brief construct an ADI Port from an index
164+ *
165+ * This constructor is private to enforce the use of the `from_char` and `from_index` member
166+ * functions. Having this construct be public defeats the purpose of this class, which is to
167+ * prevent bugs by abstracting the port index.
168+ */
169+ explicit constexpr AdiPort (uint8_t index)
134170 : m_index(index) {}
171+
172+ uint8_t m_index;
135173};
136174
137175namespace ports {
138- constexpr auto PORT_A = AdiPort::from_letter(' A' );
139- constexpr auto PORT_B = AdiPort::from_letter(' B' );
140- constexpr auto PORT_C = AdiPort::from_letter(' C' );
141- constexpr auto PORT_D = AdiPort::from_letter(' D' );
142- constexpr auto PORT_E = AdiPort::from_letter(' E' );
143- constexpr auto PORT_F = AdiPort::from_letter(' F' );
144- constexpr auto PORT_G = AdiPort::from_letter(' G' );
145- constexpr auto PORT_H = AdiPort::from_letter(' H' );
146-
176+ /*
177+ * ADI ports have a char from 'A' to 'H'. While compile-time error checking could prevent an invalid
178+ * port being constructed, the error messages that would be produced wouldn't be very concise.
179+ * However, if the user tried constructing a device on the imaginary port I, the project wouldn't
180+ * compile since PORT_I isn't declared. This error message is much clearer.
181+ */
182+ constexpr auto PORT_A = AdiPort::from_char(' A' );
183+ constexpr auto PORT_B = AdiPort::from_char(' B' );
184+ constexpr auto PORT_C = AdiPort::from_char(' C' );
185+ constexpr auto PORT_D = AdiPort::from_char(' D' );
186+ constexpr auto PORT_E = AdiPort::from_char(' E' );
187+ constexpr auto PORT_F = AdiPort::from_char(' F' );
188+ constexpr auto PORT_G = AdiPort::from_char(' G' );
189+ constexpr auto PORT_H = AdiPort::from_char(' H' );
147190} // namespace ports
148191} // namespace zest
0 commit comments