import { mapArray } from '../../../deps'
import { toKey } from '../../attributes/properties/toKey'
import { isArray } from '../../array/check/isArray'
import { isNil } from '../../primitive/nil'
import { isSymbol } from '../../primitive/symbol/isSymbol'
import { EMPTY_STRING } from '../../NATIVE/CONSTANTS/NATIVE_EMPTY_LIST'
import { isString } from './isString'
/**
*
* Converts `value` to a string. An empty string is returned for `null`
* and `undefined` values. The sign of `-0` is preserved.
* @memberOf cast
* @since 5.0.0-beta.6
*
* @param value The value to convert.
* @return Returns the converted string.
*
* @fork 4.0.0
* @category Lang
*
* @see http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tostring
* @see https://github.com/svaarala/duktape/issues/204
* @see https://github.com/substack/json-stable-stringify
* @see https://github.com/nickyout/fast-stable-stringify
* @see https://hacks.mozilla.org/2012/12/performance-with-javascript-string-objects/
*
* @example
*
* toString(null)
* //=> ''
*
* toString(-0)
* //=> '-0'
*
* toString([1, 2, 3])
* //=> '1,2,3'
*
*/
function castToString(value: any): string {
if (isNil(value)) {
return EMPTY_STRING
} else if (isString(value)) {
// Exit early for strings to avoid a performance hit in some environments.
return value as string
} else if (isArray(value)) {
// Recursively convert values (susceptible to call stack limits).
return `${mapArray(
value,
(other: any) => (isNil(other) ? other : castToString(other))
)}`
} else if (isSymbol(value)) {
return Symbol.toString.call(value)
} else {
// e.g. isNumber
return toKey(value) as string
}
}
export { castToString, castToString as toString }
export default castToString