1vectbl_names2 <- function(x,
2                          .name_repair = c("check_unique", "unique", "universal", "minimal"),
3                          quiet = FALSE) {
4
5  name <- vec_names2(x, repair = "minimal", quiet = quiet)
6  repaired_names(name, repair_hint = TRUE, .name_repair = .name_repair, quiet = quiet)
7}
8
9set_repaired_names <- function(x,
10                               repair_hint,
11                               .name_repair = c("check_unique", "unique", "universal", "minimal"),
12                               quiet = FALSE) {
13  set_names(x, repaired_names(names2(x), repair_hint, .name_repair = .name_repair, quiet = quiet))
14}
15
16repaired_names <- function(name,
17                           repair_hint,
18                           .name_repair = c("check_unique", "unique", "universal", "minimal"),
19                           quiet = FALSE,
20                           details = NULL) {
21
22  subclass_name_repair_errors(name = name, details = details, repair_hint = repair_hint,
23    vec_as_names(name, repair = .name_repair, quiet = quiet || !is_character(.name_repair))
24  )
25}
26
27# Errors ------------------------------------------------------------------
28
29error_column_names_cannot_be_empty <- function(names, repair_hint, parent = NULL) {
30  tibble_error(invalid_df("must be named", names, use_repair(repair_hint)), names = names, parent = parent)
31}
32
33error_column_names_cannot_be_dot_dot <- function(names, repair_hint, parent = NULL) {
34  tibble_error(invalid_df("must not have names of the form ... or ..j", names, use_repair(repair_hint)), names = names, parent = parent)
35}
36
37error_column_names_must_be_unique <- function(names, repair_hint, parent = NULL) {
38  tibble_error(pluralise_commas("Column name(s) ", tick(names), " must not be duplicated.", use_repair(repair_hint)), names = names, parent = parent)
39}
40
41# Subclassing errors ------------------------------------------------------
42
43subclass_name_repair_errors <- function(expr, name, details = NULL, repair_hint = FALSE) {
44  withCallingHandlers(
45    expr,
46
47    # FIXME: use cnd$names with vctrs >= 0.3.0
48    vctrs_error_names_cannot_be_empty = function(cnd) {
49      cnd <- error_column_names_cannot_be_empty(detect_empty_names(name), parent = cnd, repair_hint = repair_hint)
50      cnd$body <- details
51
52      cnd_signal(cnd)
53    },
54    vctrs_error_names_cannot_be_dot_dot = function(cnd) {
55      cnd <- error_column_names_cannot_be_dot_dot(detect_dot_dot(name), parent = cnd, repair_hint = repair_hint)
56      cnd_signal(cnd)
57    },
58    vctrs_error_names_must_be_unique = function(cnd) {
59      cnd <- error_column_names_must_be_unique(detect_duplicates(name), parent = cnd, repair_hint = repair_hint)
60      cnd_signal(cnd)
61    }
62  )
63}
64
65# Anticipate vctrs 0.3.0 release: locations replaced by names
66detect_empty_names <- function(names) {
67  which(names == "")
68}
69detect_dot_dot <- function(names) {
70  grep("^[.][.](?:[.]|[1-9][0-9]*)$", names)
71}
72detect_duplicates <- function(names) {
73  names[which(duplicated(names))]
74}
75