Add new restructureOrLines match target + update join command to use it

This commit is contained in:
2026-03-05 10:09:26 -06:00
parent d296646d4f
commit c9f41c2905
3 changed files with 27 additions and 12 deletions

View File

@@ -26,6 +26,15 @@ export const joinDestructured = (val: StrDestructured['value']): string =>
.map(part => `${part.prefix || ''}${part.value}`) .map(part => `${part.prefix || ''}${part.value}`)
.join('') .join('')
export const destructureToLines = (val: string): StrDestructured['value'] => val
.split('\n')
.map((line, idx) => {
if ( idx ) {
return { prefix: '\n', value: line }
}
return { value: line }
})
export type StrRVal = export type StrRVal =
{ term: 'string', value: string, literal?: true } { term: 'string', value: string, literal?: true }
| { term: 'int', value: number } | { term: 'int', value: number }

View File

@@ -20,7 +20,7 @@ export class Join extends Command<{ with?: StrTerm }> {
execute(vm: StrVM, data: { with?: StrTerm }): Awaitable<StrVM> { execute(vm: StrVM, data: { with?: StrTerm }): Awaitable<StrVM> {
return vm.replaceContextMatchingTerm(ctx => ({ return vm.replaceContextMatchingTerm(ctx => ({
restructure: parts => { restructureOrLines: parts => {
if ( data.with ) { if ( data.with ) {
return parts return parts
.map(part => part.value) .map(part => part.value)

View File

@@ -1,6 +1,6 @@
import {Awaitable, JSONData} from "../util/types.js"; import {Awaitable, JSONData} from "../util/types.js";
import { import {
CommandData, CommandData, destructureToLines,
isStrRVal, joinDestructured, StrDestructured, isStrRVal, joinDestructured, StrDestructured,
StrLVal, StrLVal,
StrRVal, StrRVal,
@@ -77,6 +77,11 @@ export type TermOperator = {
string?: string | ((sub: string) => Awaitable<string>), string?: string | ((sub: string) => Awaitable<string>),
/** Map `destructured` to `string`. */ /** Map `destructured` to `string`. */
restructure?: (sub: StrDestructured['value']) => Awaitable<string>, restructure?: (sub: StrDestructured['value']) => Awaitable<string>,
/**
* If `string`, destructure to lines, then map.
* If `destructured`, map directly.
*/
restructureOrLines?: (sub: StrDestructured['value']) => Awaitable<string>,
/** Map `destructured` to `destructured`. */ /** Map `destructured` to `destructured`. */
destructured?: (sub: StrDestructured['value']) => Awaitable<StrDestructured['value']>, destructured?: (sub: StrDestructured['value']) => Awaitable<StrDestructured['value']>,
/** /**
@@ -180,22 +185,18 @@ export class ExecutionContext {
return return
} }
if ( (sub.term === 'int' || sub.term === 'string') && operator.restructureOrLines ) {
this.subject = wrapString(await operator.restructureOrLines(destructureToLines(unwrapString(sub))))
return
}
if ( (sub.term === 'int' || sub.term === 'string') && operator.stringOrDestructuredPart ) { if ( (sub.term === 'int' || sub.term === 'string') && operator.stringOrDestructuredPart ) {
this.subject = wrapString(await operator.stringOrDestructuredPart(unwrapString(sub))) this.subject = wrapString(await operator.stringOrDestructuredPart(unwrapString(sub)))
return return
} }
if ( (sub.term === 'int' || sub.term === 'string') && operator.destructuredOrLines ) { if ( (sub.term === 'int' || sub.term === 'string') && operator.destructuredOrLines ) {
const fake: StrDestructured['value'] = unwrapString(sub) const rejoined = (await operator.destructuredOrLines(destructureToLines(unwrapString(sub))))
.split('\n')
.map((line, idx) => {
if ( idx ) {
return { prefix: '\n', value: line }
}
return { value: line }
})
const rejoined = (await operator.destructuredOrLines(fake))
.map(x => x.value) .map(x => x.value)
.join('\n') .join('\n')
@@ -208,6 +209,11 @@ export class ExecutionContext {
return return
} }
if ( sub.term === 'destructured' && operator.restructureOrLines ) {
this.subject = wrapString(await operator.restructureOrLines(unwrapDestructured(sub)))
return
}
if ( sub.term === 'destructured' && operator.destructured ) { if ( sub.term === 'destructured' && operator.destructured ) {
this.subject = wrapDestructured(await operator.destructured(unwrapDestructured(sub))) this.subject = wrapDestructured(await operator.destructured(unwrapDestructured(sub)))
return return