egna

2.0.2 • Public • Published

egna

npm version

Pattern matching in JS

import { match } from 'egna';

[ Try egna in your browser ]

Example

import { match, lt } from 'egna';
 
let car = async () => ({ make: 'Toyota', year: 1968 });
 
car()
  .match(
    { make: 'Subaru'}, 'Subaru',
  
    { year: lt(1950) }, car => `Super old ${car.make}`,
 
    { make: 'Toyota' }, ({ year }) => `Toyota from ${year}`,
 
    _ => {throw 'I dont recognize this car'}
  )
  .then(console.log)
  .catch( (e) => console.log("error: " + e) );
  
// prints "Toyota from 1968"

Match anything

match(
  'literal pattern', handlerFunc,
 
  [1, 2, 3], myArrayHandlerFunc,
 
  { my: { object: 'pattern' } }, 'Handlers can be just data also',
 
  _ => 'Single expression/literal at the end is the any handler'
);

Scenarios

Filter/map/reduce/etc

import { match, gt } from 'egna';
 
let cars = [{ emissions: 2500 }, { emissions: 60000 }];
 
let greenCars = cars.filter(
  match(
    { emissions: lt(3000) }, true,
    _ => false
  )
);
 
// greenCars = [{ emissions: 2500 }]

Promises

The egna module adds a match function to Promise.prototype.match. Meaning you can call match on any Promise generated from the global Promise prototype.

import 'egna'; // only have to import once anywhere in the project
 
let promise = async () => "hello";
 
promise()
  .match(
    "hello", "Hello, world!",
    _ => "Goodbye"
  )
  .then(console.log);
// return value of the matched handler is passed along the promise chain

Pattern reuse

A call to match returns function loaded with the patterns and handlers. This function can be stored and used whenever.

import { match, gt } from 'egna';
 
let httpPattern =
  match(
    { status: 404 }, 'Not found',
    { status: 200 }, 'Ok',
    { status: gt(499) }, 'Server error',
    'Unknown'
  );
 
// Use it multiple times
const msg = httpPattern(httpObject);
const msg2 = httpPattern(httpObject2);

Matchlet functions

A function anywhere in a pattern will be evaluated in place of the usual comparison, returning true/false.

Matchlet-generators included in egna:

Name Matches
gt Greater than arg
lt Less than arg
op Optional, value exists in the argument array.

Use egna's matchlets

import { match, gt, lt, op } from 'egna';
 
match(
  gt(10), () => 'greater than 10',
 
  lt(5), () => 'less than 5',
 
  op([6, 7]), () => 'either 6 or 7',
 
  _ => 'something else'
)

or make your own

const even = n => n % 2 == 0;
 
match(
  even, () => 'even number',
  _ => 'odd number'
)(34)
 
// returns 'even number'

More examples

tc39 proposal example:

fetch(jsonService)
  .match(
    { status: 200 }, ({ headers: { 'Content-Length': s } }) => {
      console.log(`size is ${s}`)
    },
    { status: 404 }, () => {
      console.log('JSON not found')
    },
    { status: gt(399) }, () => {
      throw new RequestError(res)
    }
  )

Package Sidebar

Install

npm i egna

Weekly Downloads

14

Version

2.0.2

License

MIT

Unpacked Size

18.9 kB

Total Files

8

Last publish

Collaborators

  • kahole