<commit_before>/* @flow */
import toCssValue from './toCssValue'
import type {ToCssOptions as Options, JssStyle} from '../types'

/**
 * Indent a string.
 * http://jsperf.com/array-join-vs-for
 */
function indentStr(str: string, indent: number): string {
  let result = ''
  for (let index = 0; index < indent; index++) result += '  '
  return result + str
}

/**
 * Converts a Rule to CSS string.
 */
export default function toCss(selector: string, style: JssStyle, options: Options = {}): string {
  let {indent = 0} = options
  const {fallbacks} = style
  let result = ''

  indent++

  // Apply fallbacks first.
  if (fallbacks) {
    // Array syntax {fallbacks: [{prop: value}]}
    if (Array.isArray(fallbacks)) {
      for (let index = 0; index < fallbacks.length; index++) {
        const fallback = fallbacks[index]
        for (const prop in fallback) {
          const value = fallback[prop]
          if (value != null) {
            result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
          }
        }
      }
    }
    // Object syntax {fallbacks: {prop: value}}
    else {
      for (const prop in fallbacks) {
        const value = fallbacks[prop]
        if (value != null) {
          result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
        }
      }
    }
  }

  for (const prop in style) {
    let value = style[prop]
    if (typeof value === 'function') {
      value = style[`$${prop}`]
    }
    if (value != null && prop !== 'fallbacks') {
      result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
    }
  }

  if (!result) return result

  indent--
  result = indentStr(`${selector} {${result}\n`, indent) + indentStr('}', indent)

  return result
}<commit_msg>Fix addRule for functional values, fix #475<commit_after>/* @flow */
import toCssValue from './toCssValue'
import type {ToCssOptions as Options, JssStyle} from '../types'

/**
 * Indent a string.
 * http://jsperf.com/array-join-vs-for
 */
function indentStr(str: string, indent: number): string {
  let result = ''
  for (let index = 0; index < indent; index++) result += '  '
  return result + str
}

/**
 * Converts a Rule to CSS string.
 */
export default function toCss(selector: string, style: JssStyle, options: Options = {}): string {
  let {indent = 0} = options
  const {fallbacks} = style
  let result = ''

  indent++

  // Apply fallbacks first.
  if (fallbacks) {
    // Array syntax {fallbacks: [{prop: value}]}
    if (Array.isArray(fallbacks)) {
      for (let index = 0; index < fallbacks.length; index++) {
        const fallback = fallbacks[index]
        for (const prop in fallback) {
          const value = fallback[prop]
          if (value != null) {
            result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
          }
        }
      }
    }
    // Object syntax {fallbacks: {prop: value}}
    else {
      for (const prop in fallbacks) {
        const value = fallbacks[prop]
        if (value != null) {
          result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
        }
      }
    }
  }

  let hasFunctionValue = false

  for (const prop in style) {
    let value = style[prop]
    if (typeof value === 'function') {
      value = style[`$${prop}`]
      hasFunctionValue = true
    }
    if (value != null && prop !== 'fallbacks') {
      result += `\n${indentStr(`${prop}: ${toCssValue(value)};`, indent)}`
    }
  }

  if (!result && !hasFunctionValue) return result

  indent--
  result = indentStr(`${selector} {${result}\n`, indent) + indentStr('}', indent)

  return result
}
{'fraction_non_alphanumeric': 0.1678224687933426, 'fraction_numerical': 0.0024965325936199723, 'mean_word_length': 2.6096096096096097, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3555803', 'n_tokens_mistral': 1163, 'n_tokens_neox': 1146, 'n_words': 326}