All Downloads are FREE. Search and download functionalities are using the official Maven repository.

raw.compiler.Docs.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2023 RAW Labs S.A.
 *
 * Use of this software is governed by the Business Source License
 * included in the file licenses/BSL.txt.
 *
 * As of the Change Date specified in that file, in accordance with
 * the Business Source License, use of this software will be governed
 * by the Apache License, Version 2.0, included in the file
 * licenses/APL.txt.
 */

package raw.compiler

/**
 * Package documentation.
 *
 * @param description Description of package.
 * @param info Text prefixed with Info sign.
 * @param warning Text prefixed with Warning sign.
 * @param danger Text prefixed with Danger sign.
 */
final case class PackageDoc(
    description: String,
    info: Option[String] = None,
    warning: Option[String] = None,
    danger: Option[String] = None
) {
  Doc.grammarCheck(description)
  Doc.grammarCheck(info)
  Doc.grammarCheck(warning)
  Doc.grammarCheck(danger)
}

/**
 * Package entry documentation.
 *
 * @param summary Short-form documentation for the entry.
 * @param description Long-form documentation for the entry.
 * @param example Usage example.
 * @param params Documentation of parameters.
 * @param ret Documentation of return value.
 * @param info Text prefixed with Info sign.
 * @param warning Text prefixed with Warning sign.
 * @param danger Text prefixed with Danger sign.
 */
final case class EntryDoc(
    summary: String,
    description: Option[String] = None,
    examples: List[ExampleDoc] = List.empty,
    params: List[ParamDoc] = List.empty,
    ret: Option[ReturnDoc] = None,
    info: Option[String] = None,
    warning: Option[String] = None,
    danger: Option[String] = None
) {

  Doc.grammarCheck(description)
  Doc.grammarCheck(info)
  Doc.grammarCheck(warning)
  Doc.grammarCheck(danger)

  assert(!summary.contains('\n'), "Summary must not contain newlines.")

}

final case class ExampleDoc(
    example: String,
    result: Option[String] = None
) {
  if (example.contains("```")) throw new AssertionError(
    "Example code contains ``` and this isn't supported. Must only contain RQL2 code."
  )
//  if (
//    !example.contains("s3://") && !example.contains("https://") && !example
//      .contains("http://") && example.contains("//")
//  ) throw new AssertionError(
//    "Example result contains // and this isn't supported. Use the result field instead."
//  )
  result.foreach { r =>
    if (r.contains("```")) throw new AssertionError(
      "Return contains ``` and this isn't supported. Must contain only data."
    )
    if (r.contains("//")) throw new AssertionError(
      "Return contains // and this isn't supported. Must contain only data."
    )
  }
}

/**
 * Documentation for a parameter.
 *
 * @param name Name of the parameter.
 * @param typeDoc Type documentation.
 * @param description Description of the parameter.
 * @param isOptional True/False.
 * @param isVarArg True/False.
 * @param info Text prefixed with Info sign.
 * @param warning Text prefixed with Warning sign.
 * @param danger Text prefixed with Danger sign.
 */
final case class ParamDoc(
    name: String,
    typeDoc: TypeDoc,
    description: String,
    isOptional: Boolean = false,
    isVarArg: Boolean = false,
    info: Option[String] = None,
    warning: Option[String] = None,
    danger: Option[String] = None,
    customSyntax: Option[String] = None
) {

  Doc.grammarCheck(description)
  Doc.grammarCheck(info)
  Doc.grammarCheck(warning)
  Doc.grammarCheck(danger)

}

/**
 * Return documentation.
 *
 * @param description Description of the return value.
 * @param retType Return type.
 */
final case class ReturnDoc(description: String, retType: Option[TypeDoc]) {
  Doc.grammarCheck(description)
}

/**
 * Type documentation.
 *
 * @param possibleTypes List of types allowed. It's a list because can be more than one type accepted.
 */
final case class TypeDoc(possibleTypes: List[String]) {

  // Assert that list of possible types is within the accepted list.
  possibleTypes.foreach(t =>
    assert(TypeDoc.ACCEPTED_TYPES.contains(t), s"Type documentation contains unknown type: '$t'")
  )

}

object TypeDoc {
  val ACCEPTED_TYPES = Seq(
    "any",
    // Numbers
    "byte",
    "short",
    "int",
    "long",
    "float",
    "double",
    "decimal",
    "number",
    // Binary
    "binary",
    // Boolean
    "bool",
    // String
    "string",
    // Regular expression
    "regex",
    // Collections
    "collection",
    "list",
    // Function
    "function",
    // Temporals
    "date",
    "time",
    "timestamp",
    "interval",
    "temporal",
    // Location
    "location",
    // Type
    "type",
    // Record
    "record",
    // TODO (msb): To reconsider or maybe even drop!!!
    "anything",
    // Composed types
    "list(string)",
    "collection(string)",
    "record(status: int, data: binary, headers: list(record(_1: string, _2: string))))",
    "collection(int)",
    "list(int)",
    "record(format: string, comment: string, type: string, properties: list(record(name: string, value: string)), is_collection: bool, columns: list(record(col_name: string, col_type: string, nullable: bool)), sampled: bool)",
    "list(record(url: string, metadata: record(modified: timestamp, size: int, blocks: list(record(hosts: list(string), offset: long, length: long)))",
    "list(long)",
    "collection(long)",
    "list(timestamp)",
    "collection(timestamp)"
  )
}

object Doc {

  def grammarCheck(sentence: String): Unit = {
    if (sentence.isEmpty) {
      throw new AssertionError("Empty doc")
    } else if (sentence.last != '.') {
      throw new AssertionError(s"Sentence does not terminate in a dot or semi-colon: '$sentence'.")
    }
  }

  def grammarCheck(maybeSentence: Option[String]): Unit = {
    maybeSentence.map(grammarCheck)
  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy