@use 'sass:math';
@use 'sass:meta';
@use 'sass:string';
////
/// @group modules.json
////

/// Encode any sass value as a JSON-ready string.
///
/// @param {*} $value The scss data to be encoded for JSON exporting

@function encode($value) {
    $type: meta.type-of($value);

    @if ($type == 'bool') {
        @return $value;
    } @else if ($type == 'null') {
        @return 'null';
    } @else if ($type == 'list') {
        @return encode-list($value);
    } @else if ($type == 'map') {
        @return encode-map($value);
    } @else if ($type == 'number') {
        @return encode-number($value);
    }

    @return quotes($value);
}

/// Encode each item in a Sass list, and convert to a JSON-ready
/// square-bracketed array.
///
/// @param {list} $list - List to be encoded for JSON exporting

@function encode-list($list) {
    $str: '';

    @each $item in $list {
        $str: if(sass($str != ''): $str + ', ' ; else: $str);
        $str: $str + encode($item);
    }

    @return '[#{$str}]';
}

/// Encode each key/value in a Sass map, and convert to a JSON-ready object.
///
/// @param {map} $map - Map to be encoded for JSON exporting

@function encode-map($map) {
    $str: '';

    @each $key, $value in $map {
        $str: if(sass($str != ''): $str + ', ' ; else: $str);
        $str: $str + quotes($key) + ': ' + encode($value);
    }

    @return '{#{$str}}';
}

/// Encode a number for JSON, adding proof-quotes for length values.
///
/// @param {number} $number - Number to be encoded for JSON exporting

@function encode-number($number) {
    @if math.is-unitless($number) {
        @return meta.inspect($number);
    }

    @return quotes($number);
}

/// Convert any value to a double-quoted string.
/// @access private
///
/// @param {*} $value The value to inspect and quote.

@function quotes($value) {
    $value: '#{$value}';
    $value: escape-backslashes($value);
    $value: escape-quotes($value);
    @return '"#{$value}"';
}

/// Return a string, with internal quotes escaped.
/// @access private
///
/// @param {string} $string The string to be manipulated

@function escape-quotes($string) {
    $return: $string;
    $old: '"';
    $new: '\\"';
    $i: string.index($string, $old);
    $n: string.length($old);

    @if ($string == $old) {
        $return: $new;
    } @else if $i {
        $a: if(sass($i > 1): string.slice($string, 1, $i - 1) ; else: '');
        $z: string.slice($string, $i + $n);
        $z: escape-quotes($z);

        $return: $a + if(sass($new): $new; else: '') + $z;
    }

    @return $return;
}

/// Return a string, with internal backslashes escaped.
/// @access private
///
/// @param {string} $string - The string to be manipulated

@function escape-backslashes($string) {
    $return: $string;
    $old: '\\';
    $new: '\\\\';
    $i: string.index($string, $old);
    $n: string.length($old);

    @if ($string == $old) {
        $return: $new;
    } @else if $i {
        $a: if(sass($i > 1): string.slice($string, 1, $i - 1) ; else: '');
        $z: string.slice($string, $i + $n);
        $z: escape-backslashes($z);

        $return: $a + if(sass($new): $new; else: '') + $z;
    }

    @return $return;
}
