Skip to content

Commit

Permalink
feat(context): refactor context into class (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
fu050409 authored Jan 9, 2025
1 parent 0d1e641 commit 7ef1753
Show file tree
Hide file tree
Showing 9 changed files with 90 additions and 43 deletions.
5 changes: 5 additions & 0 deletions .changeset/cuddly-brooms-agree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Refactor `Context` into a js class
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/global.cts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ const main = defineCommand({
dev,
},
callback: (ctx: Context) => {
console.log(ctx.args.config)
console.log(ctx.get('config'))
},
})

Expand Down
50 changes: 29 additions & 21 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,27 +24,6 @@ export declare function defineCommand(options: Command): Command
* @returns {void}
*/
export declare function run(cmd: Command, args?: Array<string> | undefined | null): void
/**
* Command context
*
* This is the context object that is passed to the command callback.
*/
export interface Context {
/**
* Parsed arguments
*
* This is a js object that contains the parsed arguments.
* The keys of the object are the names of the arguments and
* the values are the parsed values.
*/
args: Record<string, any>
/**
* Raw arguments
*
* The raw arguments parsed by command line or manually given.
*/
rawArgs: Array<string>
}
/** Command metadata */
export interface CommandMeta {
/**
Expand Down Expand Up @@ -235,3 +214,32 @@ export interface Command {
callback?: (ctx: Context) => void
subcommands?: Record<string, Command>
}
/**
* Command context
*
* This is the context object that is passed to the command callback.
*/
export declare class Context {
/**
* Raw arguments
*
* The raw arguments parsed by command line or manually given.
*/
rawArgs: string[]
/**
* Create a new command context
*
* This method is used to create a new command context,
* and is not intended to be used directly.
*
* @param args - Parsed arguments
* @param raw_args - Raw arguments
*/
constructor(args: Record<string, any>, raw_args: string[])
/** Get the parsed arguments */
get args(): Record<string, any>
/** Get the raw arguments */
getRawArgs(): string[]
/** Get the argument value by specified key */
get(key: string): any
}
3 changes: 2 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ if (!nativeBinding) {
throw new Error(`Failed to load native binding`)
}

const { defineCommand, run } = nativeBinding
const { defineCommand, run, Context } = nativeBinding

module.exports.defineCommand = defineCommand
module.exports.run = run
module.exports.Context = Context
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ pub mod command;
pub mod resolver;
pub mod types;
pub mod utils;

pub type HashMap<K, V> = rustc_hash::FxHashMap<K, V>;
3 changes: 1 addition & 2 deletions src/resolver.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use rustc_hash::FxHashMap as HashMap;

use crate::{
types::{Command, CommandMeta, CommandOption},
utils::{leak_borrowed_str, leak_borrowed_str_or_default, leak_str},
HashMap,
};

pub(crate) fn resolve_option_args(
Expand Down
44 changes: 40 additions & 4 deletions src/types.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,62 @@
use napi::{JsFunction, JsObject};
use napi_derive::napi;

pub use rustc_hash::FxHashMap as HashMap;
use crate::HashMap;

/// Command context
///
/// This is the context object that is passed to the command callback.
#[napi(object)]
#[napi]
pub struct Context {
/// Parsed arguments
///
/// This is a js object that contains the parsed arguments.
/// The keys of the object are the names of the arguments and
/// the values are the parsed values.
#[napi(ts_type = "Record<string, any>")]
pub args: JsObject,
args: JsObject,
/// Raw arguments
///
/// The raw arguments parsed by command line or manually given.
#[napi(ts_type = "string[]")]
pub raw_args: Vec<String>,
}

#[napi]
impl Context {
/// Create a new command context
///
/// This method is used to create a new command context,
/// and is not intended to be used directly.
///
/// @param args - Parsed arguments
/// @param raw_args - Raw arguments
#[napi(
constructor,
ts_args_type = "args: Record<string, any>, raw_args: string[]"
)]
pub fn new(args: JsObject, raw_args: Vec<String>) -> Self {
Self { args, raw_args }
}

/// Get the parsed arguments
#[napi(getter, ts_return_type = "Record<string, any>")]
pub fn args(&self) -> &JsObject {
&self.args
}

/// Get the raw arguments
#[napi(ts_return_type = "string[]")]
pub fn get_raw_args(&self) -> &Vec<String> {
&self.raw_args
}

/// Get the argument value by specified key
#[napi(ts_return_type = "any")]
pub fn get(&self, key: String) -> napi::Result<JsObject> {
self.args.get_named_property(&key)
}
}

/// Command metadata
#[napi(object)]
#[derive(Clone)]
Expand Down
12 changes: 4 additions & 8 deletions src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use std::collections::HashMap;

use napi::{Env, JsNull, JsObject, Result};

use crate::types::{Command, Context};
use crate::HashMap;

const ISSUE_LINK: &str = "https://github.com/noctisynth/archons/issues";

Expand Down Expand Up @@ -93,7 +92,7 @@ pub(crate) fn parse_arguments_inner<'arg>(
mut global_options: HashMap<String, &'static str>,
mut global_args: Vec<&'arg clap::Arg>,
) -> napi::Result<()> {
let mut options: HashMap<String, &'static str> = HashMap::new();
let mut options: HashMap<String, &'static str> = HashMap::default();
options.extend(global_options.clone());
for (name, option) in &cmd.options {
let parser = leak_borrowed_str_or_default(option.parser.as_ref().clone(), "string");
Expand Down Expand Up @@ -133,10 +132,7 @@ pub(crate) fn parse_arguments_inner<'arg>(
global_args,
)?;
} else {
let context = Context {
args: parsed_args,
raw_args,
};
let context = Context::new(parsed_args, raw_args);
if let Some(cb) = cmd.callback.as_ref() {
cb.call1::<Context, JsNull>(context)?;
} else {
Expand Down Expand Up @@ -165,7 +161,7 @@ pub(crate) fn parse_arguments<'arg>(
cmd,
matches,
raw_args,
HashMap::new(),
HashMap::default(),
Vec::new(),
)
}

0 comments on commit 7ef1753

Please sign in to comment.