33
44// TODO:(miyauci) Packaging and externalization this module.
55
6- import { isNumber } from "./deps.ts" ;
6+ import { isNonNegativeInteger , isNumber } from "./deps.ts" ;
77
88export interface ContentRange {
99 readonly rangeUnit : string ;
@@ -25,7 +25,10 @@ export interface UnsatisfiedRange {
2525 readonly completeLength : number ;
2626}
2727
28- /** Deserialize {@link ContentRange} into string. */
28+ /** Deserialize {@link ContentRange} into string.
29+ *
30+ * @throws {TypeError } If the {@link ContentRange} is invalid.
31+ */
2932export function stringify ( contentRange : ContentRange ) : string {
3033 const fmt = isRangeResp ( contentRange . range )
3134 ? stringifyRangeResp ( contentRange . range )
@@ -45,19 +48,61 @@ function stringifyRangeResp(rangeResp: RangeResp): string {
4548function stringifyInclRange ( inclRange : InclRange ) : string {
4649 const { firstPos, lastPos } = inclRange ;
4750
51+ assertNonNegativeInteger (
52+ firstPos ,
53+ Msg . InvalidNonNegativeInt ( ABNF . FirstPos , firstPos ) ,
54+ ) ;
55+
56+ assertNonNegativeInteger (
57+ lastPos ,
58+ Msg . InvalidNonNegativeInt ( ABNF . LastPos , lastPos ) ,
59+ ) ;
60+
4861 return `${ firstPos } -${ lastPos } ` ;
4962}
5063
5164function stringifyContentLength ( completeLength : number | undefined ) : string {
52- const length = isNumber ( completeLength ) ? completeLength : "*" ;
65+ if ( ! isNumber ( completeLength ) ) return "*" ;
66+
67+ assertNonNegativeInteger (
68+ completeLength ,
69+ Msg . InvalidNonNegativeInt ( ABNF . CompleteLength , completeLength ) ,
70+ ) ;
5371
54- return length . toString ( ) ;
72+ return completeLength . toString ( ) ;
5573}
5674
5775function stringifyUnsatisfiedRange ( unsatisfiedRange : UnsatisfiedRange ) : string {
58- return `*/${ unsatisfiedRange . completeLength } ` ;
76+ const { completeLength } = unsatisfiedRange ;
77+
78+ assertNonNegativeInteger (
79+ completeLength ,
80+ Msg . InvalidNonNegativeInt ( ABNF . CompleteLength , completeLength ) ,
81+ ) ;
82+
83+ return `*/${ completeLength } ` ;
5984}
6085
6186function isRangeResp ( rangeLike : RangeLike ) : rangeLike is RangeResp {
6287 return "firstPos" in rangeLike ;
6388}
89+
90+ const enum ABNF {
91+ CompleteLength = "<complete-length>" ,
92+ FirstPos = "<first-pos>" ,
93+ LastPos = "<last-pos>" ,
94+ }
95+
96+ const Msg = {
97+ InvalidNonNegativeInt : ( subject : string , actual : unknown ) =>
98+ `${ subject } is not non-negative integer. ${ actual } ` ,
99+ } ;
100+
101+ function assertNonNegativeInteger (
102+ input : number ,
103+ msg ?: string ,
104+ ) : asserts input {
105+ if ( ! isNonNegativeInteger ( input ) ) {
106+ throw TypeError ( msg ) ;
107+ }
108+ }
0 commit comments