• Stars
    star
    130
  • Rank 277,575 (Top 6 %)
  • Language
    Rust
  • License
    MIT License
  • Created almost 5 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Text calculator with support for units and conversion

cpc

calculation + conversion

cpc parses and evaluates strings of math, with support for units and conversion. 128-bit decimal floating points are used for high accuracy.

It also lets you mix units, so for example 1 km - 1m results in 999 Meter.

Crates.io Documentation

List of all supported units

CLI Installation

Install using cargo:

cargo install cpc

To install it manually, grab the appropriate binary from the GitHub Releases page and place it wherever you normally place binaries on your OS.

CLI Usage

cpc '2h/3 to min'

API Installation

Add cpc as a dependency in Cargo.toml.

API Usage

use cpc::eval;
use cpc::units::Unit;

match eval("3m + 1cm", true, Unit::Celsius, false) {
    Ok(answer) => {
        // answer: Number { value: 301, unit: Unit::Centimeter }
        println!("Evaluated value: {} {:?}", answer.value, answer.unit)
    },
    Err(e) => {
        println!("{e}")
    }
}

Examples

3 + 4 * 2

8 % 3

(4 + 1)km to light years

10m/2s * 5 trillion s

1 lightyear * 0.001mm in km2

1m/s + 1mi/h in kilometers per h

round(sqrt(2)^4)! liters

10% of abs(sin(pi)) horsepower to watts

Supported unit types

  • Normal numbers
  • Time
  • Length
  • Area
  • Volume
  • Mass
  • Digital storage (bytes etc)
  • Energy
  • Power
  • Electric current
  • Resistance
  • Voltage
  • Pressure
  • Frequency
  • Speed
  • Temperature

Accuracy

cpc uses 128-bit Decimal Floating Point (d128) numbers instead of Binary Coded Decimals for better accuracy. The result cpc gives will still not always be 100% accurate. I would recommend rounding the result to 20 decimals or less.

Performance

It's pretty fast and scales well. In my case, it usually runs in under 0.1ms. The biggest performance hit is functions like log(). log(12345) evaluates in 0.12ms, and log(e) in 0.25ms.

To see how fast it is, you can pass the --verbose flag in CLI, or the verbose argument to eval().

Dev Instructions

Get started

Install Rust.

Run cpc with a CLI argument as input:

cargo run -- '100ms to s'

Run in verbose mode, which shows some extra logs:

cargo run -- '100ms to s' --verbose

Run tests:

cargo test

Build:

cargo build

Adding a unit

Nice resources for adding units:

1. Add the unit

In src/units.rs, units are specified like this:

pub enum UnitType {
  Time,
  // etc
}

// ...

create_units!(
  Nanosecond:         (Time, d128!(1)),
  Microsecond:        (Time, d128!(1000)),
  // etc
)

The number associated with a unit is it's "weight". For example, if a second's weight is 1, then a minute's weight is 60.

2. Add a test for the unit

Make sure to also add a test for each unit. The tests look like this:

assert_eq!(convert_test(1000.0, Meter, Kilometer), 1.0);

Basically, 1000 Meter == 1 Kilometer.

3. Add the unit to the lexer

Text is turned into tokens (some of which are units) in lexer.rs. Here's one example:

// ...
match string {
  "h" | "hr" | "hrs" | "hour" | "hours" => tokens.push(Token::Unit(Hour)),
  // etc
}
// ...

Potential Improvements

  • Support for conversion between Power, Current, Resistance and Voltage. Multiplication and division is currently supported, but not conversions using sqrt or pow.
  • Move to pure-rust decimal implementation
    • rust_decimal: Only supports numbers up to ~1E+29
    • bigdecimal: Lacking math functions
  • E notation, like 2E+10
  • Unit types

Releasing a new version

  1. Update CHANGELOG.md
  2. Bump the version number in Cargo.toml
  3. Run cargo test
  4. Create a git tag in format v#.#.#
  5. Add release notes to the generated GitHub release and publish it
  6. Run cargo publish

More Repositories

1

date-picker-svelte

Date and time picker for Svelte
Svelte
309
star
2

tauri-sveltekit-template

Tauri + SvelteKit template
Rust
164
star
3

kadium

App for staying ontop of YouTube channels' uploads
Svelte
109
star
4

time-machine-inspector

Time Machine backup size inspector app
Rust
89
star
5

mr-tagger

Music file tagging app for Mac, Linux and Windows
Rust
74
star
6

remind-me-again

Toggleable cron reminders app for Mac, Linux and Windows
Rust
72
star
7

ferrum

Music library app for Mac, Linux and Windows
Svelte
45
star
8

svelte-tauri-filedrop

Tauri file drop handling component for Svelte
Svelte
33
star
9

svelte-droplet

File dropzone for Svelte
Svelte
32
star
10

redlux

AAC decoder for MPEG-4 and AAC files, with rodio support
Rust
18
star
11

readme-template-action

Integrate GitHub API data in your README.md
TypeScript
14
star
12

color-picker-svelte

Color picker for Svelte
Svelte
9
star
13

modal-svelte

Svelte
9
star
14

thumbnail-grabber

Chrome extension for grabbing thumbnails/covers
TypeScript
6
star
15

vidl

CLI for downloading video/audio
Python
5
star
16

homebrew-tap

My Homebrew casks and formulas
Ruby
5
star
17

notifier

Android app for scheduling notifications
Dart
4
star
18

starchart

GitHub star history graph
Svelte
4
star
19

embler

Turn binaries into applications
JavaScript
3
star
20

taskler

Simple text editor for your New Tab page
Stylus
3
star
21

colorboy-js

Easy terminal coloring for Node.js, macOS/Linux
JavaScript
2
star
22

tauri-multiwindow-freeze-bug

Rust
1
star
23

svelte-template

Svelte + Vite + HMR + TypeScript + Preprocessor support
JavaScript
1
star
24

kasper.space

Personal website
Vue
1
star
25

2dcam

After Effects 2d camera
JavaScript
1
star
26

to

CLI audio, video and image file converter
Shell
1
star
27

cryp

Cryptocurrency portfolio tracker (unfinished)
JavaScript
1
star
28

vite-plugin-electron-x

A Vite plugin for bundling `main.ts`, `preload.ts` and running Electron in development
TypeScript
1
star
29

colorboy-py

python package - Easily add color to your strings
Python
1
star
30

gpm-to-itunes

Imports Google Play Music library to iTunes
Python
1
star
31

portal-removechild-bug

Svelte
1
star
32

lumix

Art website (unfinished)
JavaScript
1
star
33

javascript-without-snippets

Atom package | language-javascript without snippets
CoffeeScript
1
star
34

website-template

My PHP website template
PHP
1
star
35

tauri-devtools-resize-bug

Rust
1
star