_disjointVersionsAll(vers, vers.length, 0);
}

export function toDirString(ver: FlowVersion): string {
  switch (ver.kind) {
    case 'all':
      return 'flow_all';

    case 'specific': {
      let str = `flow_v${ver.ver.major}.${ver.ver.minor}`;
      if (ver.ver.patch !== null) {
        str += `.${ver.ver.patch}`;
        if (ver.ver.prerel) {
          str += `-${ver.ver.prerel}`;
        }
      }
      return str;
    }

    case 'ranged': {
      const {lower, upper} = ver;
      let str = 'flow_';
      if (lower !== null) {
        str += `v${lower.major}.${lower.minor}`;
        if (lower.patch !== null) {
          str += `.${lower.patch}`;
          if (lower.prerel !== null) {
            str += `-${lower.prerel}`;
          }
        }
      }

      str += '-';

      if (upper !== null) {
        str += `v${upper.major}.${upper.minor}`;
        if (upper.patch !== null) {
          str += `.${upper.patch}`;
          if (upper.prerel !== null) {
            str += `-${upper.prerel}`;
          }
        }
      }
      return str;
    }

    default:
      (ver: empty);
      throw new Error('Unexpected FlowVersion kind!');
  }
}

export function toSemverString(ver: FlowVersion): string {
  switch (ver.kind) {
    case 'all':
      return 'vx.x.x';

    case 'specific':
      return toDirString(ver).substr('flow_'.length);

    case 'ranged': {
      const {upper, lower} = ver;
      let str = '';
      if (lower !== null) {
        str += `>=v${lower.major}.${lower.minor}`;
        if (lower.patch !== null) {
          str += `.${lower.patch}`;
          if (lower.prerel !== null) {
            str += `-${lower.prerel}`;
          }
        }
Given an array of versions, returns whether they are mutually disjoint.