WebURL Documentation Beta

Protocol Substitution​Map

public protocol SubstitutionMap 

A bidirectional map of ASCII code-points.

Some legacy encodings require certain ASCII code-points to be replaced. For example, the application/x-www-form-urlencoded encoding does not percent-encode ASCII spaces (0x20) as "%20", and instead replaces them with a "+" (0x2B). The following example shows a potential implementation of this encoding:

struct FormEncoding: PercentEncodeSet {

  func shouldPercentEncode(ascii codePoint: UInt8) -> Bool {
    if codePoint == 0x20 { return false } // do not percent-encode spaces, substitute instead.
    if codePoint == 0x2B { return true }  // percent-encode actual "+"s in the source.
    // other codepoints...
  }

  struct Substitutions: SubstitutionMap {
    func substitute(ascii codePoint: UInt8) -> UInt8? {
      codePoint == 0x20 ? 0x2B : nil // Substitute spaces with "+".
    }
    func unsubstitute(ascii codePoint: UInt8) -> UInt8? {
      codePoint == 0x2B ? 0x20 : nil // Unsubstitute "+" to space.
    }
  }

  var substitutions: Substitutions { .init() }
}

Default Implementations

none

@inlinable
public static var none: NoSubstitutions 

No substitutions. This is the substitution map used by all encode-sets specified in the URL standard, except form-encoding.

form​Encoding

@inlinable
public static var formEncoding: URLEncodeSet.FormEncoding.Substitutions 

Substitutions applicable to the application/x-www-form-urlencoded percent-encode set.

Requirements

substitute(ascii:​)

func substitute(ascii codePoint: UInt8) -> UInt8?

Returns the substitute to use for the given code-point, or nil if the code-point does not require substitution.

The ASCII percent sign (0x25) and alpha characters (0x41...0x5A and 0x61...0x7A) must not be substituted.

In order to ensure lossless encoding, any code-points returned as substitutes should be percent-encoded by the substitution map's parent encoder and restored by the inverse function, unsubstitute(ascii:).

Parameters

code​Point UInt8

An ASCII code-point from unencoded data. Always in the range 0...127.

Returns

The code-point to emit instead of codePoint, or nil if codePoint should not be substituted. Substitute code-points must always be in the range 0...127.

unsubstitute(ascii:​)

func unsubstitute(ascii codePoint: UInt8) -> UInt8?

Returns the code-point restored from the given substitute code-point, or nil if the given code-point is not a substitute.

In order to ensure lossless encoding, this function should restore all code-points substituted by substitute(ascii:).

Parameters

code​Point UInt8

An ASCII codepoint from encoded data. Always in the range 0...127.

Returns

The code-point to emit instead of codePoint, or nil if codePoint is not a substitute recognized by this substitution map. Restored code-points must always be in the range 0...127.