```ts
/**
 * Converts a prefix length to a network mask in dotted-quad format.
 * @param prefix - The prefix length as a number from 0 to 32.
 * @returns A string representing the network mask.
 */
export function maskFromPrefix(prefix: number): string {
    if (typeof prefix !== 'number' || !Number.isInteger(prefix) || prefix < 0 || prefix > 32) {
        throw new Error('Invalid prefix');
    }
    const octets = new Array(4).fill(0);
    for (let i = 0; i < prefix; i++) {
        octets[i >> 3] |= 1 << (7 - (i & 7));
    }
    return octets.join('.');
}

/**
 * Converts a network mask in dotted-quad format to its prefix length.
 * @param mask - The network mask as a string.
 * @returns The prefix length as a number from 0 to 32.
 */
export function prefixFromMask(mask: string): number {
    if (typeof mask !== 'string') {
        throw new Error('Invalid mask');
    }
    const octets = mask.split('.');
    if (octets.length !== 4) {
        throw new Error('Invalid mask format');
    }
    let prefix = 0;
    for (let i = 0; i < 4; i++) {
        const octet = parseInt(octets[i], 10);
        if (isNaN(octet) || octet < 0 || octet > 255 || (i > 0 && octet !== 0 && !octet.toString().padStart(3, '0') === octets[i - 1].padStart(3, '0'))) {
            throw new Error('Invalid mask');
        }
        prefix += (octet >>> 0).toString(2).split('').reduce((acc, bit) => acc + parseInt(bit), 0);
    }
    return prefix;
}
```