001package io.avaje.json.mapper;
002
003import java.util.Map;
004import java.util.Optional;
005
006/**
007 * A helper to extract values from a Map.
008 * <p>
009 * The <em>path</em> can be simple like {@code "name"} or a nested path using
010 * dot notation like {@code "address.city"}.
011 * <p>
012 * For extracting numbers there are methods for int, long and double that will
013 * return the intValue(), longValue() and doubleValue() respectively.
014 * <p>
015 * <pre>{@code
016 *
017 *   String json = "{\"name\":\"Rob\",\"score\":4.5,\"whenActive\":\"2025-10-20\",\"address\":{\"street\":\"Pall Mall\"}}";
018 *   Map<String, Object> mapFromJson = jsonMapper.fromJsonObject(json);
019 *
020 *   JsonExtract jsonExtract = jsonMapper.extract(mapFromJson);
021 *
022 *   String name = jsonExtract.extract("name");
023 *   double score = jsonExtract.extract("score", -1D);
024 *   String street = jsonExtract.extract("address.street");
025 *
026 *   LocalDate activeDate = jsonExtract.extractOrEmpty("whenActive")
027 *     .map(LocalDate::parse)
028 *     .orElseThrow();
029 *
030 * }</pre>
031 *
032 */
033public interface JsonExtract {
034
035  /**
036   * Return a JsonExtract for the given Map of values.
037   */
038  static JsonExtract of(Map<String, Object> map) {
039    return new DExtract(map);
040  }
041
042  /**
043   * Extract the text from the node at the given path.
044   *
045   * @throws IllegalArgumentException When the given path is missing.
046   */
047  String extract(String path);
048
049  /**
050   * Extract the text value from the given path if present else empty.
051   *
052   * <pre>{@code
053   *
054   *   LocalDate activeDate = jsonExtract.extractOrEmpty("whenActive")
055   *     .map(LocalDate::parse)
056   *     .orElseThrow();
057   *
058   * }</pre>
059   */
060  Optional<String> extractOrEmpty(String path);
061
062  /**
063   * Extract the text value from the given path if present or the given default value.
064   *
065   * @param missingValue The value to use when the path is missing.
066   */
067  String extract(String path, String missingValue);
068
069  /**
070   * Extract the int from the given path if present or the given default value.
071   *
072   * @param missingValue The value to use when the path is missing.
073   */
074  int extract(String path, int missingValue);
075
076  /**
077   * Extract the long from the given path if present or the given default value.
078   *
079   * @param missingValue The value to use when the path is missing.
080   */
081  long extract(String path, long missingValue);
082
083  /**
084   * Extract the double from the given path if present or the given default value.
085   *
086   * @param missingValue The value to use when the path is missing.
087   */
088  double extract(String path, double missingValue);
089
090  /**
091   * Extract the boolean from the given path if present or the given default value.
092   *
093   * @param missingValue The value to use when the path is missing.
094   */
095  boolean extract(String path, boolean missingValue);
096}