npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

derive-rust

v0.1.1

Published

javascript utilities inspired by the Rust programming language and its standard library

Downloads

987

Readme

derive-rust

javascript utilities inspired by the Rust programming language and its standard library

Option<T>

const a: Option<string> = Some("hello");
const b: Option<string> = None(); 
const c = None<string>();

Result<T, E>

const fooOk: Result<{result: boolean}, {}> = Ok({result: true});
const fooErr: Result<{result: boolean}, {}> = Err({});

Match

You can use match function with primitive and object data. Primitive and Objects implemented by Sized<T> can be used for "refutable" pattern

const s1 = match(Some("bar"), (v) => [ // v = Some("bar")
  [Some("baz"), () => "baz"],
  [None<string>(), () => "none"]
], (v, s) => ""); // v = Some("bar"), s = "bar"

console.log(s1) // ""

const s2 = match(Some("bar"), (v) => [
  [Some("baz"), Some("bar"), () => "baz or bar"], // arm with more than one value
  [None<string>(), () => "none"]
], (_, s) => s);

console.log(s2) // "baz or bar"

const s3 = match(Some("bar"), (v) => [
  (bar) => [Some("baz"), Some(bar), () => "baz or " + bar], // pattern is used by wrapping in functions
  [None<string>(), () => "none"]
], (_, s) => s);

console.log(s3) // "baz or bar"


const val = match(9, () => [
  [3, () => Some(3)],
  [0, () => None()],
  v => [v, () => Some(v + 1)] // pattern sample with primitives 
], () => None())

console.log(val.unwrap()) // 10

Don't compare functions

    cmp(() => {}, () => {}) // 0. Zero means ignoring truthy/falsy case
// So

const o1 = {
    a: 1,
    barFn() {}
}

const o2 = {
    a: 1,
    fooFn() {}
}

cmp(o1, o2) // 1 - means true
eq(o1, o2) // true. It's just wrapper to cmp(o1, o2) === 1


// But their types are different 

partialEq(o1, o2) // false. As it's generic wrapper to eqType()

My vision of enum definition with generic


class MyEnum<T = string> implements Sized<T> {
  $ref: [T] = [MyEnum.name] as [T];
  variant: [string | T] = [""]; // must be public for cmp() function

  #variant(value: T | Function | string): MyEnum<T> {
    setNoncallableRef(this, value) as MyEnum<T> // or this.$ref[0] = value;
    this.variant = [fn.name]; // this value additionally guarantees that the object is unique
    Object.freeze(this);

    return this; 
  }

  Foo() {
    return this.variant(this.Foo);
  }

  Bar() {
    return this.variant("baz")
  }
}

const result = match(new MyEnum().Bar(), () => [
  (v) => [new MyEnum().Foo(), () => v],
  (v) => [new MyEnum().Bar(), () => v]
], () => "");

console.log(result) // "Bar"

Declarations

class Option<T> implements Sized<T> {
    #private;
    $ref: [T];
    $option: [string, T];
    some(value: T): Option<T>;
    none(): Option<T>;
    unwrap(): T;
    expect(message: string): T;
    unwrapOr(value: T): T;
    isNone(): boolean;
    isSome(): boolean;
    intoResult<E>(error: E): Result<T, E>;
    static from<T>(value: T): Option<T>;
    static None<T = unknown>(): Option<T>;
    static Some<T>(value: T): Option<T>;
}

class Result<T, E> implements Sized<T | E> {
    #private;
    $ref: [T | E];
    $result: [string, T | E];
    ok(value: T): Result<T, E>;
    err(value: E): Result<T, E>;
    isOk(): boolean;
    isErr(): boolean;
    expect(message: string): T;
    unwrap(): T;
    unwrapOr(value: T): T;
    unwrapErr(): E;
    intoOption(): Option<T>;
    static from<T, E>(value: T | E): Result<T, E>;
    static Ok<T, E>(value: T): Result<T, E>;
    static Err<E, T>(value: E): Result<T, E>;
}

match<V, T>(value: V, matchArms: (value: V) => Array<MatchArm<V, T> | MatchArmFn<V, T>>, defaultMatchArm: (value: V, p: Extract<V>) => T): T;

ifLet<V>(p: (p: Extract<V>) => V, value: V, ifExpr: (v: Extract<V>) => void, elseExpr?: (v: Extract<V>) => void): void;

interface Sized<T = null> {
    readonly $ref: [T];
}

type Self<S, T = void> = (self: S) => T; 
// You can define 
constructor(impl: (self: Class) => TypeYouWant) { impl(this) }
// or 
constructor(self: Self<Class, TypeYouWant>) { self(this) } // the same

type Nothing = {};
type Unit = {};

function eqType(lhs: any, rhs: any): boolean;
function cmp<T>(lhs: T, rhs: T): 1 | -1 | 0;
function orderKeys(keys: string[], targetKeys: string[]): string[];
function partialEq<T>(lhs: T, rhs: T): boolean;
function eq<T>(lhs: T, rhs: T): boolean;
function unit(): Unit;
function nothing(): Nothing;
function ref<T, R>(self: Sized<R>, fn: (r: R) => T): T;
function panic(reason: string): never;
function ex<T, V>(fn: (value: V) => T, value?: V): T; // any expression just like (function(value) {})(value) . Parameter not required
function dex<I, O, V>(input: (value: V) => I, output: (value: ReturnType<typeof input>) => O, value?: V): O; // double expression
function getRef<T>(s: Sized<T>): T;
function setNoncallableRef<T>(self: Sized<T>, value: T): Sized<T>;
function setRef<T>(self: Sized<T>, value: T): Sized<T>;
function range(start: number, end: number): number[];
function rangeInc(start: number, end: number): number[];
function rangeChars(start: string, end: string, str: string): string[];
function rangeCharsInc(start: string, end: string, str: string): string[];
function rangeCharsRev(start: string, end: string, str: string): string[];
function rangeCharsRevInc(start: string, end: string, str: string): string[];
function clone<T>(value: T): T;

function syncChannel<T>(): [SyncSender<T>, SyncReceiver<T>];

const [tx,rx] = syncChannel();

tx.send(1) // returns Result<{}, SenderError> to check if valid value has been sent
tx.send(2)
rx.recv() // returns Option<T>. In this case Some(1)

function channel<T>(): [Sender<T>, Receiver<T>]; // async channel. 
// send(async() => {}) -> void
// recv() ->  Promise<Result<T, ReceiverError<E>>>