jaq icon indicating copy to clipboard operation
jaq copied to clipboard

Provide a more complete example for jaq_core

Open the80srobot opened this issue 1 month ago • 5 comments

The example code in jaq_core is incomplete and not practically usable:

  • It doesn't load the standard library (and basically tells you to figure it out yourself)
  • It doesn't explain concepts like Arena, or what the loader does, etc
  • It doesn't say where errors can arise at runtime and how to catch them

Just a tiny bit more explanation would go a long way.

the80srobot avatar Nov 21 '25 16:11 the80srobot

I agree with you. Would you like to contribute by expanding the example code / documentation in a way that you see fit?

01mf02 avatar Nov 22 '25 12:11 01mf02

Hi! I actually gave up on that approach and what I did instead is basically clone the entire jaq crate, removing the main function and calling real_main directly as needed.

It's a little hard to tell with things changing now around 3.0.0-alpha, but it looks like you might need a larger refactor to make the language embeddable the way e.g. lua is.

But it looks to me like that refactor might actually just be:

  • Make a crate called something like jaq-embed
  • Do what I did, remove main and turn real_main into the entry point.
  • Rename the Cli struct into something like Options and make it slightly nicer to use programmatically
  • Then just change jaq to be a layer on top that

Does that seem completely off and like I missed something about the architecture? Or does it sound reasonable?

the80srobot avatar Nov 22 '25 12:11 the80srobot

Poking around the internals a little more, I think two current design decisions are really limiting.

  • One is the assumption that the filter will output directly to stdout. This is mostly just baked into jaq and not any of the other crates, and could probably be changed so that the API takes a impl Write.
  • The second one is harder to change and that is the decision to basically not support --slurp. (It's kind of supported, but doesn't combine the inputs into one array, so it's basically the same as calling the filter multiple times.) This might make sense for the CLI, but it's complicating when you're trying to use it programmatically.

So to amend, I think the intermediate crate jaq-embed would need the following modifications:

  • Take all the options normally provided on the Cli + an impl Write for output. The Cli struct is already fairly easy to use, it would need only a few minor conveniences, like maybe automatically serializing struct arguments from Rust.
  • Allow real slurping of inputs, so that batched processing is possible.

I think then you'd end up with an API that can run a jq program programmatically with real ease and allow you to capture output without blocking off stdin globally.

the80srobot avatar Nov 22 '25 16:11 the80srobot

(In case it's not obvious, I am offering to do that when I have a spare weekend.)

the80srobot avatar Nov 22 '25 16:11 the80srobot

@the80srobot, it would help me to better understand your use case for jaq's API. Do you want to make a CLI, for example? Where should your inputs come from? Where should your outputs go? Are you running user-provided (arbitrary) programs, or only fixed ones?

I have started some work in #375. My current vision is to make most building blocks of the jaq crate available in some crate (currently jaq-bla in lack of a good name). I'm not sure whether CLI parsing should go into that crate, but many other things currently in the jaq crate should.

01mf02 avatar Nov 26 '25 11:11 01mf02