[READ-ONLY] Mirror of https://github.com/probablykasper/cpc. Text calculator with support for units and conversion cpc.kasper.space
calculator cli conversion converter library math package units units-converter wasm website
0

Configure Feed

Select the types of activity you want to include in your feed.

Fix unit printing

Kasper (Jun 24, 2026, 8:54 AM +0200) 9fe708e1 192cc293

+32 -8
+32 -8
src/lib.rs
··· 24 24 25 25 use crate::units::{Unit, UnitType, primitive_unit}; 26 26 use fastnum::{D128, dec128 as d}; 27 - use std::fmt::{self, Display}; 27 + use std::{ 28 + cmp::Reverse, 29 + fmt::{self, Display}, 30 + }; 28 31 use web_time::Instant; 29 32 30 33 /// Turns an [`AstNode`](parser::AstNode) into a [`Number`] ··· 60 63 /// The unit and exponent 61 64 pub unit: Vec<(Unit, isize)>, 62 65 } 63 - 64 66 impl Number { 65 67 pub fn new_unitless(value: D128) -> Number { 66 68 Number { ··· 94 96 } 95 97 fn get_unit_string(&self, plural: bool) -> String { 96 98 let mut s = String::new(); 97 - for unit in &self.unit { 98 - match unit.1.is_positive() { 99 - true if s.len() == 0 => (), 100 - true => s.push_str(" * "), 101 - false => s.push_str(" / "), 99 + let mut units = self.unit.clone(); 100 + units.sort_by_key(|u| { 101 + ( 102 + u.1 < 0, // multiplications first 103 + Reverse(u.1.abs()), // largest first, like "sqm seconds" 104 + ) 105 + }); 106 + let mut positives = units.iter().filter(|u| u.1 > 0).peekable(); 107 + while let Some(unit) = positives.next() { 108 + if unit.1 <= 0 { 109 + continue; 102 110 } 103 - match plural { 111 + if s.len() != 0 { 112 + s.push_str(" * "); 113 + } 114 + // only the last multiplication should be plural: `100 minute meters / volt hour` 115 + let is_last = positives.peek().is_none(); 116 + match is_last && plural { 104 117 false => s.push_str(unit.0.singular()), 105 118 true => s.push_str(unit.0.plural()), 106 119 }; 120 + if unit.1.abs() >= 2 { 121 + s.push_str("^"); 122 + s.push_str(&unit.1.to_string()); 123 + } 124 + } 125 + for unit in units { 126 + if unit.1 >= 0 { 127 + continue; 128 + } 129 + s.push_str(" / "); 130 + s.push_str(unit.0.singular()); 107 131 if unit.1.abs() >= 2 { 108 132 s.push_str("^"); 109 133 s.push_str(&unit.1.to_string());