Skip to content

Commit

Permalink
Support full & basic parsing 🎉
Browse files Browse the repository at this point in the history
  • Loading branch information
xxczaki committed Jan 19, 2020
1 parent e5667a8 commit 27056b8
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/cashify.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Options} from './lib/options';
import convert from './convert';
import parse from './utils/parser';

export default class Cashify {
constructor(public readonly options: Partial<Options>) { }
Expand All @@ -10,12 +11,11 @@ export default class Cashify {
* @return Conversion result.
*/
convert(amount: number | string, options?: Partial<Options>): number {
// If provided `amount` is a string, get the right amount and detect the `from` currency
// If provided `amount` is a string, use parsing
if (typeof amount === 'string') {
const from = amount.replace(/(?<currency_code>[^A-Za-z])/g, '');
amount = parseFloat(amount.replace(/[^0-9-.]/g, ''));
const data = parse(amount);

return convert(amount, {...this.options, from, ...options} as Options);
return convert(data.amount, {...this.options, from: data.from, to: data.to, ...options} as Options);
}

return convert(amount, {...this.options, ...options} as Options);
Expand Down
8 changes: 4 additions & 4 deletions src/convert.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import getRate from './lib/get-rate';
import {Options} from './lib/options';
import parse from './utils/parser';

/**
* @param amount Amount of money you want to convert.
* @param options Conversion options.
* @return Conversion result.
*/
export default function convert(amount: number | string, {from, to, base, rates}: Options): number {
// If provided `amount` is a string, get the right amount and detect the `from` currency
// If provided `amount` is a string, use parsing
if (typeof amount === 'string') {
from = amount.replace(/(?<currency_code>[^A-Za-z])/g, '');
amount = parseFloat(amount.replace(/[^0-9-.]/g, ''));
const data = parse(amount);

return (amount * 100) * getRate(base, rates, from, to) / 100;
return (data.amount * 100) * getRate(base, rates, data.from ?? from, data.to ?? to) / 100;
}

return (amount * 100) * getRate(base, rates, from, to) / 100;
Expand Down
36 changes: 36 additions & 0 deletions src/utils/parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
interface Options {
amount: number;
from: string | undefined;
to: string | undefined;
}

/**
* Expression parser
* @param expression Expression you want to parse, ex. `10 usd to pln` or `€1.23 eur`
* @return Object with parsing results
*/
export default function parse(expression: string): Options {
const amount = parseFloat(expression.replace(/[^0-9-.]/g, '')) || undefined;
let from;
let to;

// Search for `to` keyword (case insensitive) to split the expression into 2 parts
if (/to/i.exec(expression)) {
const firstPart = expression.slice(0, expression.search(/to/i)).toUpperCase().trim();

from = firstPart.replace(/(?<currency_code>[^A-Za-z])/g, '');
to = expression.slice(expression.search(/to/i) + 2).toUpperCase().trim();
} else {
from = expression.replace(/(?<currency_code>[^A-Za-z])/g, '');
}

if (amount === undefined) {
throw new Error('Could not parse the `amount` argument. Make sure it includes at least a valid amount.');
}

return {
amount,
from: from.toUpperCase() || undefined,
to
};
}

0 comments on commit 27056b8

Please sign in to comment.