Skip to content

Commit

Permalink
feat: Allow Parameters to be Bare Array of Items
Browse files Browse the repository at this point in the history
Parameters may now be both Bare Items and Bare Array of Item (effectively an unparameterized InnerList).

This implements the proposal in httpwg/http-extensions#2732 that effectively allows nesting of parameters.
  • Loading branch information
Rahul Gupta authored and CxRes committed Oct 3, 2024
1 parent 6d4f30b commit 32b10de
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 14 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "structured-headers",
"version": "2.0.0-alpha.1",
"name": "@cxres/structured-headers",
"version": "2.0.0-alpha.1-nesting.0",
"description": "Implementation of RFC8941, structured headers for HTTP.",
"type": "module",
"exports": "./dist/index.js",
Expand Down
30 changes: 23 additions & 7 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,17 @@ export default class Parser {

}

private parseInnerList(): InnerList {
private parseBareItemOrBareItemArray(): BareItem|Item[] {

if (this.lookChar()==='(') {
return this.parseBareItemArray();
} else {
return this.parseBareItem();
}

}

private parseBareItemArray(): Item[] {

this.expectChar('(');
this.pos++;
Expand All @@ -143,10 +153,7 @@ export default class Parser {
this.skipWS();
if (this.lookChar() === ')') {
this.pos++;
return [
innerList,
this.parseParameters()
];
return innerList;
}

innerList.push(this.parseItem(false));
Expand All @@ -162,6 +169,15 @@ export default class Parser {

}

private parseInnerList(): InnerList {

return [
this.parseBareItemArray(),
this.parseParameters()
];

}

private parseBareItem(): BareItem {

const char = this.lookChar();
Expand Down Expand Up @@ -204,10 +220,10 @@ export default class Parser {
this.pos++;
this.skipWS();
const key = this.parseKey();
let value: BareItem = true;
let value: BareItem|Item[] = true;
if (this.lookChar() === '=') {
this.pos++;
value = this.parseBareItem();
value = this.parseBareItemOrBareItemArray();
}
parameters.set(key, value);
}
Expand Down
14 changes: 10 additions & 4 deletions src/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,12 @@ export function serializeItem(input: Item|BareItem, params?: Parameters): string

}

export function serializeInnerList(input: InnerList): string {

return `(${input[0].map(value => serializeItem(value)).join(' ')})${serializeParameters(input[1])}`;
export function serializeBareItemArray(input: Item[]): string {
return `(${input.map(value => serializeItem(value)).join(' ')})`;
}

export function serializeInnerList(input: InnerList): string {
return `${serializeBareItemArray(input[0])}${serializeParameters(input[1])}`;
}


Expand Down Expand Up @@ -180,7 +182,11 @@ export function serializeParameters(input: Parameters): string {

let out = ';' + serializeKey(key);
if (value!==true) {
out+='=' + serializeBareItem(value);
if (Array.isArray(value)) {
out+='=' + serializeBareItemArray(value);
} else {
out+='=' + serializeBareItem(value);
}
}
return out;

Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type InnerList = [Item[], Parameters];
* Parameters they occur within, and the values are bare items (i.e., they
* themselves cannot be parameterized
*/
export type Parameters = Map<string, BareItem>;
export type Parameters = Map<string, BareItem|Item[]>;

/**
* Dictionaries are ordered maps of key-value pairs, where the keys are short
Expand Down

0 comments on commit 32b10de

Please sign in to comment.