code_ownership 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/.cargo/config +2 -2
  3. data/Cargo.lock +9 -2
  4. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.cargo-checksum.json +1 -1
  5. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/Cargo.lock +8 -1
  6. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/Cargo.toml +2 -1
  7. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_generator.rs +119 -9
  8. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/validator.rs +77 -15
  9. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/executable_name_config_test.rs +25 -4
  10. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/.github/CODEOWNERS +1 -1
  11. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/.github/CODEOWNERS +1 -1
  12. data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/invalid_project_test.rs +30 -0
  13. data/ext/cargo-vendor/similar-2.7.0/.cargo/config.toml +2 -0
  14. data/ext/cargo-vendor/similar-2.7.0/.cargo-checksum.json +1 -0
  15. data/ext/cargo-vendor/similar-2.7.0/.cargo_vcs_info.json +6 -0
  16. data/ext/cargo-vendor/similar-2.7.0/.github/FUNDING.yml +1 -0
  17. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/clippy.yml +16 -0
  18. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/rustfmt.yml +16 -0
  19. data/ext/cargo-vendor/similar-2.7.0/.github/workflows/tests.yml +49 -0
  20. data/ext/cargo-vendor/similar-2.7.0/.vscode/settings.json +5 -0
  21. data/ext/cargo-vendor/similar-2.7.0/CHANGELOG.md +132 -0
  22. data/ext/cargo-vendor/similar-2.7.0/Cargo.lock +373 -0
  23. data/ext/cargo-vendor/similar-2.7.0/Cargo.lock.msrv +266 -0
  24. data/ext/cargo-vendor/similar-2.7.0/Cargo.toml +149 -0
  25. data/ext/cargo-vendor/similar-2.7.0/Cargo.toml.orig +73 -0
  26. data/ext/cargo-vendor/similar-2.7.0/LICENSE +201 -0
  27. data/ext/cargo-vendor/similar-2.7.0/Makefile +31 -0
  28. data/ext/cargo-vendor/similar-2.7.0/README.md +59 -0
  29. data/ext/cargo-vendor/similar-2.7.0/clippy.toml +1 -0
  30. data/ext/cargo-vendor/similar-2.7.0/examples/close-matches.rs +15 -0
  31. data/ext/cargo-vendor/similar-2.7.0/examples/large.rs +8 -0
  32. data/ext/cargo-vendor/similar-2.7.0/examples/nonstring.rs +13 -0
  33. data/ext/cargo-vendor/similar-2.7.0/examples/original-slices.rs +11 -0
  34. data/ext/cargo-vendor/similar-2.7.0/examples/patience.rs +48 -0
  35. data/ext/cargo-vendor/similar-2.7.0/examples/serde.rs +15 -0
  36. data/ext/cargo-vendor/similar-2.7.0/examples/terminal-inline.rs +60 -0
  37. data/ext/cargo-vendor/similar-2.7.0/examples/terminal.rs +20 -0
  38. data/ext/cargo-vendor/similar-2.7.0/examples/udiff.rs +24 -0
  39. data/ext/cargo-vendor/similar-2.7.0/scripts/wasmtime-wrapper.sh +4 -0
  40. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/capture.rs +117 -0
  41. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/compact.rs +351 -0
  42. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/hook.rs +178 -0
  43. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/lcs.rs +294 -0
  44. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/mod.rs +134 -0
  45. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/myers.rs +442 -0
  46. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/patience.rs +198 -0
  47. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/replace.rs +221 -0
  48. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping-2.snap +60 -0
  49. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__capture__capture_hook_grouping.snap +64 -0
  50. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__contiguous.snap +28 -0
  51. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__diff.snap +22 -0
  52. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__pat.snap +31 -0
  53. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__lcs__same.snap +12 -0
  54. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__contiguous.snap +28 -0
  55. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__deadline_reached.snap +22 -0
  56. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__diff.snap +22 -0
  57. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__myers__pat.snap +31 -0
  58. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience.snap +45 -0
  59. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/snapshots/similar__algorithms__patience__patience_out_of_bounds_bug.snap +16 -0
  60. data/ext/cargo-vendor/similar-2.7.0/src/algorithms/utils.rs +379 -0
  61. data/ext/cargo-vendor/similar-2.7.0/src/common.rs +185 -0
  62. data/ext/cargo-vendor/similar-2.7.0/src/deadline_support.rs +37 -0
  63. data/ext/cargo-vendor/similar-2.7.0/src/iter.rs +195 -0
  64. data/ext/cargo-vendor/similar-2.7.0/src/lib.rs +176 -0
  65. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff.snap +25 -0
  66. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint-2.snap +10 -0
  67. data/ext/cargo-vendor/similar-2.7.0/src/snapshots/similar__udiff__unified_diff_newline_hint.snap +11 -0
  68. data/ext/cargo-vendor/similar-2.7.0/src/text/abstraction.rs +446 -0
  69. data/ext/cargo-vendor/similar-2.7.0/src/text/inline.rs +342 -0
  70. data/ext/cargo-vendor/similar-2.7.0/src/text/mod.rs +792 -0
  71. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_ops.snap +22 -0
  72. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__captured_word_ops.snap +202 -0
  73. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__char_diff.snap +39 -0
  74. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__line_ops_inline.snap +126 -0
  75. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__inline__serde.snap +107 -0
  76. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__lifetimes_on_iter.snap +42 -0
  77. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__line_ops.snap +42 -0
  78. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde.snap +55 -0
  79. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__serde_ops.snap +38 -0
  80. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__unified_diff.snap +12 -0
  81. data/ext/cargo-vendor/similar-2.7.0/src/text/snapshots/similar__text__virtual_newlines.snap +32 -0
  82. data/ext/cargo-vendor/similar-2.7.0/src/text/utils.rs +55 -0
  83. data/ext/cargo-vendor/similar-2.7.0/src/types.rs +502 -0
  84. data/ext/cargo-vendor/similar-2.7.0/src/udiff.rs +359 -0
  85. data/ext/cargo-vendor/similar-2.7.0/src/utils.rs +412 -0
  86. data/ext/code_ownership/Cargo.toml +1 -1
  87. data/lib/code_ownership/version.rb +1 -1
  88. metadata +252 -178
  89. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/CODEOWNERS +0 -0
  90. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/audit.yml +0 -0
  91. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/ci.yml +0 -0
  92. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.github/workflows/dotslash-config.json +0 -0
  93. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.rustfmt.toml +0 -0
  94. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/.rusty-hook.toml +0 -0
  95. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/AGENTS.md +0 -0
  96. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/CLAUDE.md +0 -0
  97. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/README.md +0 -0
  98. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/dev/run_benchmarks_for_file.sh +0 -0
  99. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/dev/run_benchmarks_for_gv.sh +0 -0
  100. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/rust-toolchain.toml +0 -0
  101. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/file.rs +0 -0
  102. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/mod.rs +0 -0
  103. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cache/noop.rs +0 -0
  104. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/cli.rs +0 -0
  105. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/common_test.rs +0 -0
  106. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/config.rs +0 -0
  107. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/crosscheck.rs +0 -0
  108. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/lib.rs +0 -0
  109. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/main.rs +0 -0
  110. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/codeowners_file_parser.rs +0 -0
  111. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/codeowners_query.rs +0 -0
  112. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_owner_finder.rs +0 -0
  113. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/file_owner_resolver.rs +0 -0
  114. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/annotated_file_mapper.rs +0 -0
  115. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/directory_mapper.rs +0 -0
  116. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/escaper.rs +0 -0
  117. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/package_mapper.rs +0 -0
  118. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_gem_mapper.rs +0 -0
  119. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_glob_mapper.rs +0 -0
  120. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper/team_yml_mapper.rs +0 -0
  121. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership/mapper.rs +0 -0
  122. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/ownership.rs +0 -0
  123. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/path_utils.rs +0 -0
  124. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project.rs +0 -0
  125. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project_builder.rs +0 -0
  126. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/project_file_builder.rs +0 -0
  127. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner/api.rs +0 -0
  128. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner/types.rs +0 -0
  129. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/runner.rs +0 -0
  130. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/src/tracked_files.rs +0 -0
  131. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/cache_test.rs +0 -0
  132. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/codeowners_path_test.rs +0 -0
  133. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/common/mod.rs +0 -0
  134. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/crosscheck_owners_test.rs +0 -0
  135. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/config/code_ownership.yml +0 -0
  136. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/config/teams/test_team.yml +0 -0
  137. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/docs/CODEOWNERS +0 -0
  138. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/expected/CODEOWNERS +0 -0
  139. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_codeowners_path/ruby/app/models/test.rb +0 -0
  140. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/app/foo.rb +0 -0
  141. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/code_ownership.yml +0 -0
  142. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/teams/foo.yml +0 -0
  143. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/config/teams/payments.yml +0 -0
  144. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/custom_executable_name/ruby/app/payments/foo.rb +0 -0
  145. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/app/bar.rb +0 -0
  146. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/config/code_ownership.yml +0 -0
  147. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/default_executable_name/config/teams/bar.yml +0 -0
  148. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/.github/CODEOWNERS +0 -0
  149. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/code_ownership.yml +0 -0
  150. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payments.yml +0 -0
  151. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/config/teams/payroll.yml +0 -0
  152. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/gems/payroll_calculator/calculator.rb +0 -0
  153. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/bank_account.rb +0 -0
  154. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/blockchain.rb +0 -0
  155. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/models/payroll.rb +0 -0
  156. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/payments/nacha.rb +0 -0
  157. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/.codeowner +0 -0
  158. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/services/multi_owned.rb +0 -0
  159. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/app/unowned.rb +0 -0
  160. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/invalid_project/ruby/packages/payroll_flow/package.yml +0 -0
  161. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.github/CODEOWNERS +0 -0
  162. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/.keep +0 -0
  163. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/code_ownership.yml +0 -0
  164. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/design.yml +0 -0
  165. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/config/teams/frontend.yml +0 -0
  166. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/apps/public/index.tsx +0 -0
  167. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/package.json +0 -0
  168. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/dashboard/src/index.tsx +0 -0
  169. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/.codeowner +0 -0
  170. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/javascript_only_project/frontend/packages/ui-kit/src/button.tsx +0 -0
  171. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/.github/CODEOWNERS +0 -0
  172. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/code_ownership.yml +0 -0
  173. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/teams/bad_team.yml +0 -0
  174. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/config/teams/good.yml +0 -0
  175. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/missing_github_team/gems/pets/dog.rb +0 -0
  176. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/.github/CODEOWNERS +0 -0
  177. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/.codeowner +0 -0
  178. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/deep/nesting/nestdir/deep_file.rb +0 -0
  179. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/consumers/one_owner.rb +0 -0
  180. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/.codeowner +0 -0
  181. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/.codeowner +0 -0
  182. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/app/services/exciting/some_other_file.rb +0 -0
  183. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/code_ownership.yml +0 -0
  184. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/bar.yml +0 -0
  185. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/multiple-directory-owners/config/teams/foo.yml +0 -0
  186. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/.github/CODEOWNERS +0 -0
  187. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/.ignore +0 -0
  188. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/code_ownership.yml +0 -0
  189. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payments.yml +0 -0
  190. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/payroll.yml +0 -0
  191. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/config/teams/ux.yml +0 -0
  192. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/gems/payroll_calculator/calculator.rb +0 -0
  193. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/gems/pets/dog.rb +0 -0
  194. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/index.tsx +0 -0
  195. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/PayrollFlow/package.json +0 -0
  196. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/.codeowner +0 -0
  197. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/(special)/pay.ts +0 -0
  198. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/.codeowner +0 -0
  199. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/items/item.ts +0 -0
  200. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/javascript/packages/list/page-admin.tsx +0 -0
  201. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/bank_account.rb +0 -0
  202. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/models/payroll.rb +0 -0
  203. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/.codeowner +0 -0
  204. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/foo/ownedby_payroll.rb +0 -0
  205. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payments/nacha.rb +0 -0
  206. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/.codeowner +0 -0
  207. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/payroll/payroll.rb +0 -0
  208. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/edit.erb +0 -0
  209. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/index.html.erb +0 -0
  210. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/app/views/foos/new.html.erb +0 -0
  211. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/ignored_files/git_ignored.rb +0 -0
  212. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/ruby/packages/payroll_flow/package.yml +0 -0
  213. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project/should_be_ignored/an_ignored_file.rb +0 -0
  214. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/.github/CODEOWNERS +0 -0
  215. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/code_ownership.yml +0 -0
  216. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/brewers.yml +0 -0
  217. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/cubs.yml +0 -0
  218. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/giants.yml +0 -0
  219. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/config/teams/rockies.yml +0 -0
  220. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/package.json +0 -0
  221. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/datepicker/src/picks/dp.tsx +0 -0
  222. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/package.json +0 -0
  223. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/list/src/item.tsx +0 -0
  224. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/package.json +0 -0
  225. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/field.tsx +0 -0
  226. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/frontend/packages/components/textfield/src/fields/small.tsx +0 -0
  227. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/apollo/lib/apollo.rb +0 -0
  228. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/ivy/lib/ivy.rb +0 -0
  229. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/lager/lib/lager.rb +0 -0
  230. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/gems/summit/lib/summit.rb +0 -0
  231. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/app/services/stats.rb +0 -0
  232. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/games/package.yml +0 -0
  233. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/app/services/capacity.rb +0 -0
  234. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/locations/package.yml +0 -0
  235. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/app/services/date.rb +0 -0
  236. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/packs/schedule/package.yml +0 -0
  237. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/lib/util.rb +0 -0
  238. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/brewers/services/play.rb +0 -0
  239. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/.codeowner +0 -0
  240. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/.codeowner +0 -0
  241. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/db/price.rb +0 -0
  242. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/models/entertainment.rb +0 -0
  243. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/cubs/services/play.rb +0 -0
  244. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/giants/services/play.rb +0 -0
  245. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/fixtures/valid_project_with_overrides/ruby/app/rockies/services/play.rb +0 -0
  246. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/git_stage_test.rs +0 -0
  247. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/invalid_project_structure_test.rs +0 -0
  248. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/missing_github_team_test.rs +0 -0
  249. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/multiple_directory_owners_test.rs +0 -0
  250. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/run_config_executable_override_test.rs +0 -0
  251. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/runner_api.rs +0 -0
  252. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/untracked_files_test.rs +0 -0
  253. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/valid_project_test.rs +0 -0
  254. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/valid_project_with_overrides_test.rs +0 -0
  255. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tests/validate_files_test.rs +0 -0
  256. /data/ext/cargo-vendor/{codeowners-0.3.2 → codeowners-0.3.3}/tmp/.gitkeep +0 -0
@@ -0,0 +1,792 @@
1
+ //! Text diffing utilities.
2
+ use std::borrow::Cow;
3
+ use std::cmp::Reverse;
4
+ use std::collections::BinaryHeap;
5
+ use std::time::Duration;
6
+
7
+ mod abstraction;
8
+ #[cfg(feature = "inline")]
9
+ mod inline;
10
+ mod utils;
11
+
12
+ pub use self::abstraction::{DiffableStr, DiffableStrRef};
13
+ #[cfg(feature = "inline")]
14
+ pub use self::inline::InlineChange;
15
+
16
+ use self::utils::{upper_seq_ratio, QuickSeqRatio};
17
+ use crate::algorithms::IdentifyDistinct;
18
+ use crate::deadline_support::{duration_to_deadline, Instant};
19
+ use crate::iter::{AllChangesIter, ChangesIter};
20
+ use crate::udiff::UnifiedDiff;
21
+ use crate::{capture_diff_deadline, get_diff_ratio, group_diff_ops, Algorithm, DiffOp};
22
+
23
+ #[derive(Debug, Clone, Copy)]
24
+ enum Deadline {
25
+ Absolute(Instant),
26
+ Relative(Duration),
27
+ }
28
+
29
+ impl Deadline {
30
+ fn into_instant(self) -> Option<Instant> {
31
+ match self {
32
+ Deadline::Absolute(instant) => Some(instant),
33
+ Deadline::Relative(duration) => duration_to_deadline(duration),
34
+ }
35
+ }
36
+ }
37
+
38
+ /// A builder type config for more complex uses of [`TextDiff`].
39
+ ///
40
+ /// Requires the `text` feature.
41
+ #[derive(Clone, Debug, Default)]
42
+ pub struct TextDiffConfig {
43
+ algorithm: Algorithm,
44
+ newline_terminated: Option<bool>,
45
+ deadline: Option<Deadline>,
46
+ }
47
+
48
+ impl TextDiffConfig {
49
+ /// Changes the algorithm.
50
+ ///
51
+ /// The default algorithm is [`Algorithm::Myers`].
52
+ pub fn algorithm(&mut self, alg: Algorithm) -> &mut Self {
53
+ self.algorithm = alg;
54
+ self
55
+ }
56
+
57
+ /// Sets a deadline for the diff operation.
58
+ ///
59
+ /// By default a diff will take as long as it takes. For certain diff
60
+ /// algorithms like Myer's and Patience a maximum running time can be
61
+ /// defined after which the algorithm gives up and approximates.
62
+ pub fn deadline(&mut self, deadline: Instant) -> &mut Self {
63
+ self.deadline = Some(Deadline::Absolute(deadline));
64
+ self
65
+ }
66
+
67
+ /// Sets a timeout for thediff operation.
68
+ ///
69
+ /// This is like [`deadline`](Self::deadline) but accepts a duration.
70
+ pub fn timeout(&mut self, timeout: Duration) -> &mut Self {
71
+ self.deadline = Some(Deadline::Relative(timeout));
72
+ self
73
+ }
74
+
75
+ /// Changes the newline termination flag.
76
+ ///
77
+ /// The default is automatic based on input. This flag controls the
78
+ /// behavior of [`TextDiff::iter_changes`] and unified diff generation
79
+ /// with regards to newlines. When the flag is set to `false` (which
80
+ /// is the default) then newlines are added. Otherwise the newlines
81
+ /// from the source sequences are reused.
82
+ pub fn newline_terminated(&mut self, yes: bool) -> &mut Self {
83
+ self.newline_terminated = Some(yes);
84
+ self
85
+ }
86
+
87
+ /// Creates a diff of lines.
88
+ ///
89
+ /// This splits the text `old` and `new` into lines preserving newlines
90
+ /// in the input. Line diffs are very common and because of that enjoy
91
+ /// special handling in similar. When a line diff is created with this
92
+ /// method the `newline_terminated` flag is flipped to `true` and will
93
+ /// influence the behavior of unified diff generation.
94
+ ///
95
+ /// ```rust
96
+ /// use similar::{TextDiff, ChangeTag};
97
+ ///
98
+ /// let diff = TextDiff::configure().diff_lines("a\nb\nc", "a\nb\nC");
99
+ /// let changes: Vec<_> = diff
100
+ /// .iter_all_changes()
101
+ /// .map(|x| (x.tag(), x.value()))
102
+ /// .collect();
103
+ ///
104
+ /// assert_eq!(changes, vec![
105
+ /// (ChangeTag::Equal, "a\n"),
106
+ /// (ChangeTag::Equal, "b\n"),
107
+ /// (ChangeTag::Delete, "c"),
108
+ /// (ChangeTag::Insert, "C"),
109
+ /// ]);
110
+ /// ```
111
+ pub fn diff_lines<'old, 'new, 'bufs, T: DiffableStrRef + ?Sized>(
112
+ &self,
113
+ old: &'old T,
114
+ new: &'new T,
115
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
116
+ self.diff(
117
+ Cow::Owned(old.as_diffable_str().tokenize_lines()),
118
+ Cow::Owned(new.as_diffable_str().tokenize_lines()),
119
+ true,
120
+ )
121
+ }
122
+
123
+ /// Creates a diff of words.
124
+ ///
125
+ /// This splits the text into words and whitespace.
126
+ ///
127
+ /// Note on word diffs: because the text differ will tokenize the strings
128
+ /// into small segments it can be inconvenient to work with the results
129
+ /// depending on the use case. You might also want to combine word level
130
+ /// diffs with the [`TextDiffRemapper`](crate::utils::TextDiffRemapper)
131
+ /// which lets you remap the diffs back to the original input strings.
132
+ ///
133
+ /// ```rust
134
+ /// use similar::{TextDiff, ChangeTag};
135
+ ///
136
+ /// let diff = TextDiff::configure().diff_words("foo bar baz", "foo BAR baz");
137
+ /// let changes: Vec<_> = diff
138
+ /// .iter_all_changes()
139
+ /// .map(|x| (x.tag(), x.value()))
140
+ /// .collect();
141
+ ///
142
+ /// assert_eq!(changes, vec![
143
+ /// (ChangeTag::Equal, "foo"),
144
+ /// (ChangeTag::Equal, " "),
145
+ /// (ChangeTag::Delete, "bar"),
146
+ /// (ChangeTag::Insert, "BAR"),
147
+ /// (ChangeTag::Equal, " "),
148
+ /// (ChangeTag::Equal, "baz"),
149
+ /// ]);
150
+ /// ```
151
+ pub fn diff_words<'old, 'new, 'bufs, T: DiffableStrRef + ?Sized>(
152
+ &self,
153
+ old: &'old T,
154
+ new: &'new T,
155
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
156
+ self.diff(
157
+ Cow::Owned(old.as_diffable_str().tokenize_words()),
158
+ Cow::Owned(new.as_diffable_str().tokenize_words()),
159
+ false,
160
+ )
161
+ }
162
+
163
+ /// Creates a diff of characters.
164
+ ///
165
+ /// Note on character diffs: because the text differ will tokenize the strings
166
+ /// into small segments it can be inconvenient to work with the results
167
+ /// depending on the use case. You might also want to combine word level
168
+ /// diffs with the [`TextDiffRemapper`](crate::utils::TextDiffRemapper)
169
+ /// which lets you remap the diffs back to the original input strings.
170
+ ///
171
+ /// ```rust
172
+ /// use similar::{TextDiff, ChangeTag};
173
+ ///
174
+ /// let diff = TextDiff::configure().diff_chars("abcdef", "abcDDf");
175
+ /// let changes: Vec<_> = diff
176
+ /// .iter_all_changes()
177
+ /// .map(|x| (x.tag(), x.value()))
178
+ /// .collect();
179
+ ///
180
+ /// assert_eq!(changes, vec![
181
+ /// (ChangeTag::Equal, "a"),
182
+ /// (ChangeTag::Equal, "b"),
183
+ /// (ChangeTag::Equal, "c"),
184
+ /// (ChangeTag::Delete, "d"),
185
+ /// (ChangeTag::Delete, "e"),
186
+ /// (ChangeTag::Insert, "D"),
187
+ /// (ChangeTag::Insert, "D"),
188
+ /// (ChangeTag::Equal, "f"),
189
+ /// ]);
190
+ /// ```
191
+ pub fn diff_chars<'old, 'new, 'bufs, T: DiffableStrRef + ?Sized>(
192
+ &self,
193
+ old: &'old T,
194
+ new: &'new T,
195
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
196
+ self.diff(
197
+ Cow::Owned(old.as_diffable_str().tokenize_chars()),
198
+ Cow::Owned(new.as_diffable_str().tokenize_chars()),
199
+ false,
200
+ )
201
+ }
202
+
203
+ /// Creates a diff of unicode words.
204
+ ///
205
+ /// This splits the text into words according to unicode rules. This is
206
+ /// generally recommended over [`TextDiffConfig::diff_words`] but
207
+ /// requires a dependency.
208
+ ///
209
+ /// This requires the `unicode` feature.
210
+ ///
211
+ /// Note on word diffs: because the text differ will tokenize the strings
212
+ /// into small segments it can be inconvenient to work with the results
213
+ /// depending on the use case. You might also want to combine word level
214
+ /// diffs with the [`TextDiffRemapper`](crate::utils::TextDiffRemapper)
215
+ /// which lets you remap the diffs back to the original input strings.
216
+ ///
217
+ /// ```rust
218
+ /// use similar::{TextDiff, ChangeTag};
219
+ ///
220
+ /// let diff = TextDiff::configure().diff_unicode_words("ah(be)ce", "ah(ah)ce");
221
+ /// let changes: Vec<_> = diff
222
+ /// .iter_all_changes()
223
+ /// .map(|x| (x.tag(), x.value()))
224
+ /// .collect();
225
+ ///
226
+ /// assert_eq!(changes, vec![
227
+ /// (ChangeTag::Equal, "ah"),
228
+ /// (ChangeTag::Equal, "("),
229
+ /// (ChangeTag::Delete, "be"),
230
+ /// (ChangeTag::Insert, "ah"),
231
+ /// (ChangeTag::Equal, ")"),
232
+ /// (ChangeTag::Equal, "ce"),
233
+ /// ]);
234
+ /// ```
235
+ #[cfg(feature = "unicode")]
236
+ pub fn diff_unicode_words<'old, 'new, 'bufs, T: DiffableStrRef + ?Sized>(
237
+ &self,
238
+ old: &'old T,
239
+ new: &'new T,
240
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
241
+ self.diff(
242
+ Cow::Owned(old.as_diffable_str().tokenize_unicode_words()),
243
+ Cow::Owned(new.as_diffable_str().tokenize_unicode_words()),
244
+ false,
245
+ )
246
+ }
247
+
248
+ /// Creates a diff of graphemes.
249
+ ///
250
+ /// This requires the `unicode` feature.
251
+ ///
252
+ /// Note on grapheme diffs: because the text differ will tokenize the strings
253
+ /// into small segments it can be inconvenient to work with the results
254
+ /// depending on the use case. You might also want to combine word level
255
+ /// diffs with the [`TextDiffRemapper`](crate::utils::TextDiffRemapper)
256
+ /// which lets you remap the diffs back to the original input strings.
257
+ ///
258
+ /// ```rust
259
+ /// use similar::{TextDiff, ChangeTag};
260
+ ///
261
+ /// let diff = TextDiff::configure().diff_graphemes("💩🇦🇹🦠", "💩🇦🇱❄️");
262
+ /// let changes: Vec<_> = diff
263
+ /// .iter_all_changes()
264
+ /// .map(|x| (x.tag(), x.value()))
265
+ /// .collect();
266
+ ///
267
+ /// assert_eq!(changes, vec![
268
+ /// (ChangeTag::Equal, "💩"),
269
+ /// (ChangeTag::Delete, "🇦🇹"),
270
+ /// (ChangeTag::Delete, "🦠"),
271
+ /// (ChangeTag::Insert, "🇦🇱"),
272
+ /// (ChangeTag::Insert, "❄️"),
273
+ /// ]);
274
+ /// ```
275
+ #[cfg(feature = "unicode")]
276
+ pub fn diff_graphemes<'old, 'new, 'bufs, T: DiffableStrRef + ?Sized>(
277
+ &self,
278
+ old: &'old T,
279
+ new: &'new T,
280
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
281
+ self.diff(
282
+ Cow::Owned(old.as_diffable_str().tokenize_graphemes()),
283
+ Cow::Owned(new.as_diffable_str().tokenize_graphemes()),
284
+ false,
285
+ )
286
+ }
287
+
288
+ /// Creates a diff of arbitrary slices.
289
+ ///
290
+ /// ```rust
291
+ /// use similar::{TextDiff, ChangeTag};
292
+ ///
293
+ /// let old = &["foo", "bar", "baz"];
294
+ /// let new = &["foo", "BAR", "baz"];
295
+ /// let diff = TextDiff::configure().diff_slices(old, new);
296
+ /// let changes: Vec<_> = diff
297
+ /// .iter_all_changes()
298
+ /// .map(|x| (x.tag(), x.value()))
299
+ /// .collect();
300
+ ///
301
+ /// assert_eq!(changes, vec![
302
+ /// (ChangeTag::Equal, "foo"),
303
+ /// (ChangeTag::Delete, "bar"),
304
+ /// (ChangeTag::Insert, "BAR"),
305
+ /// (ChangeTag::Equal, "baz"),
306
+ /// ]);
307
+ /// ```
308
+ pub fn diff_slices<'old, 'new, 'bufs, T: DiffableStr + ?Sized>(
309
+ &self,
310
+ old: &'bufs [&'old T],
311
+ new: &'bufs [&'new T],
312
+ ) -> TextDiff<'old, 'new, 'bufs, T> {
313
+ self.diff(Cow::Borrowed(old), Cow::Borrowed(new), false)
314
+ }
315
+
316
+ fn diff<'old, 'new, 'bufs, T: DiffableStr + ?Sized>(
317
+ &self,
318
+ old: Cow<'bufs, [&'old T]>,
319
+ new: Cow<'bufs, [&'new T]>,
320
+ newline_terminated: bool,
321
+ ) -> TextDiff<'old, 'new, 'bufs, T> {
322
+ let deadline = self.deadline.and_then(|x| x.into_instant());
323
+ let ops = if old.len() > 100 || new.len() > 100 {
324
+ let ih = IdentifyDistinct::<u32>::new(&old[..], 0..old.len(), &new[..], 0..new.len());
325
+ capture_diff_deadline(
326
+ self.algorithm,
327
+ ih.old_lookup(),
328
+ ih.old_range(),
329
+ ih.new_lookup(),
330
+ ih.new_range(),
331
+ deadline,
332
+ )
333
+ } else {
334
+ capture_diff_deadline(
335
+ self.algorithm,
336
+ &old[..],
337
+ 0..old.len(),
338
+ &new[..],
339
+ 0..new.len(),
340
+ deadline,
341
+ )
342
+ };
343
+ TextDiff {
344
+ old,
345
+ new,
346
+ ops,
347
+ newline_terminated: self.newline_terminated.unwrap_or(newline_terminated),
348
+ algorithm: self.algorithm,
349
+ }
350
+ }
351
+ }
352
+
353
+ /// Captures diff op codes for textual diffs.
354
+ ///
355
+ /// The exact diff behavior is depending on the underlying [`DiffableStr`].
356
+ /// For instance diffs on bytes and strings are slightly different. You can
357
+ /// create a text diff from constructors such as [`TextDiff::from_lines`] or
358
+ /// the [`TextDiffConfig`] created by [`TextDiff::configure`].
359
+ ///
360
+ /// Requires the `text` feature.
361
+ pub struct TextDiff<'old, 'new, 'bufs, T: DiffableStr + ?Sized> {
362
+ old: Cow<'bufs, [&'old T]>,
363
+ new: Cow<'bufs, [&'new T]>,
364
+ ops: Vec<DiffOp>,
365
+ newline_terminated: bool,
366
+ algorithm: Algorithm,
367
+ }
368
+
369
+ impl<'old, 'new, 'bufs> TextDiff<'old, 'new, 'bufs, str> {
370
+ /// Configures a text differ before diffing.
371
+ pub fn configure() -> TextDiffConfig {
372
+ TextDiffConfig::default()
373
+ }
374
+
375
+ /// Creates a diff of lines.
376
+ ///
377
+ /// For more information see [`TextDiffConfig::diff_lines`].
378
+ pub fn from_lines<T: DiffableStrRef + ?Sized>(
379
+ old: &'old T,
380
+ new: &'new T,
381
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
382
+ TextDiff::configure().diff_lines(old, new)
383
+ }
384
+
385
+ /// Creates a diff of words.
386
+ ///
387
+ /// For more information see [`TextDiffConfig::diff_words`].
388
+ pub fn from_words<T: DiffableStrRef + ?Sized>(
389
+ old: &'old T,
390
+ new: &'new T,
391
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
392
+ TextDiff::configure().diff_words(old, new)
393
+ }
394
+
395
+ /// Creates a diff of chars.
396
+ ///
397
+ /// For more information see [`TextDiffConfig::diff_chars`].
398
+ pub fn from_chars<T: DiffableStrRef + ?Sized>(
399
+ old: &'old T,
400
+ new: &'new T,
401
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
402
+ TextDiff::configure().diff_chars(old, new)
403
+ }
404
+
405
+ /// Creates a diff of unicode words.
406
+ ///
407
+ /// For more information see [`TextDiffConfig::diff_unicode_words`].
408
+ ///
409
+ /// This requires the `unicode` feature.
410
+ #[cfg(feature = "unicode")]
411
+ pub fn from_unicode_words<T: DiffableStrRef + ?Sized>(
412
+ old: &'old T,
413
+ new: &'new T,
414
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
415
+ TextDiff::configure().diff_unicode_words(old, new)
416
+ }
417
+
418
+ /// Creates a diff of graphemes.
419
+ ///
420
+ /// For more information see [`TextDiffConfig::diff_graphemes`].
421
+ ///
422
+ /// This requires the `unicode` feature.
423
+ #[cfg(feature = "unicode")]
424
+ pub fn from_graphemes<T: DiffableStrRef + ?Sized>(
425
+ old: &'old T,
426
+ new: &'new T,
427
+ ) -> TextDiff<'old, 'new, 'bufs, T::Output> {
428
+ TextDiff::configure().diff_graphemes(old, new)
429
+ }
430
+ }
431
+
432
+ impl<'old, 'new, 'bufs, T: DiffableStr + ?Sized + 'old + 'new> TextDiff<'old, 'new, 'bufs, T> {
433
+ /// Creates a diff of arbitrary slices.
434
+ ///
435
+ /// For more information see [`TextDiffConfig::diff_slices`].
436
+ pub fn from_slices(
437
+ old: &'bufs [&'old T],
438
+ new: &'bufs [&'new T],
439
+ ) -> TextDiff<'old, 'new, 'bufs, T> {
440
+ TextDiff::configure().diff_slices(old, new)
441
+ }
442
+
443
+ /// The name of the algorithm that created the diff.
444
+ pub fn algorithm(&self) -> Algorithm {
445
+ self.algorithm
446
+ }
447
+
448
+ /// Returns `true` if items in the slice are newline terminated.
449
+ ///
450
+ /// This flag is used by the unified diff writer to determine if extra
451
+ /// newlines have to be added.
452
+ pub fn newline_terminated(&self) -> bool {
453
+ self.newline_terminated
454
+ }
455
+
456
+ /// Returns all old slices.
457
+ pub fn old_slices(&self) -> &[&'old T] {
458
+ &self.old
459
+ }
460
+
461
+ /// Returns all new slices.
462
+ pub fn new_slices(&self) -> &[&'new T] {
463
+ &self.new
464
+ }
465
+
466
+ /// Return a measure of the sequences' similarity in the range `0..=1`.
467
+ ///
468
+ /// A ratio of `1.0` means the two sequences are a complete match, a
469
+ /// ratio of `0.0` would indicate completely distinct sequences.
470
+ ///
471
+ /// ```rust
472
+ /// # use similar::TextDiff;
473
+ /// let diff = TextDiff::from_chars("abcd", "bcde");
474
+ /// assert_eq!(diff.ratio(), 0.75);
475
+ /// ```
476
+ pub fn ratio(&self) -> f32 {
477
+ get_diff_ratio(self.ops(), self.old.len(), self.new.len())
478
+ }
479
+
480
+ /// Iterates over the changes the op expands to.
481
+ ///
482
+ /// This method is a convenient way to automatically resolve the different
483
+ /// ways in which a change could be encoded (insert/delete vs replace), look
484
+ /// up the value from the appropriate slice and also handle correct index
485
+ /// handling.
486
+ pub fn iter_changes<'x, 'slf>(
487
+ &'slf self,
488
+ op: &DiffOp,
489
+ ) -> ChangesIter<'slf, [&'x T], [&'x T], &'x T>
490
+ where
491
+ 'x: 'slf,
492
+ 'old: 'x,
493
+ 'new: 'x,
494
+ {
495
+ op.iter_changes(self.old_slices(), self.new_slices())
496
+ }
497
+
498
+ /// Returns the captured diff ops.
499
+ pub fn ops(&self) -> &[DiffOp] {
500
+ &self.ops
501
+ }
502
+
503
+ /// Isolate change clusters by eliminating ranges with no changes.
504
+ ///
505
+ /// This is equivalent to calling [`group_diff_ops`] on [`TextDiff::ops`].
506
+ pub fn grouped_ops(&self, n: usize) -> Vec<Vec<DiffOp>> {
507
+ group_diff_ops(self.ops().to_vec(), n)
508
+ }
509
+
510
+ /// Flattens out the diff into all changes.
511
+ ///
512
+ /// This is a shortcut for combining [`TextDiff::ops`] with
513
+ /// [`TextDiff::iter_changes`].
514
+ pub fn iter_all_changes<'x, 'slf>(&'slf self) -> AllChangesIter<'slf, 'x, T>
515
+ where
516
+ 'x: 'slf + 'old + 'new,
517
+ 'old: 'x,
518
+ 'new: 'x,
519
+ {
520
+ AllChangesIter::new(&self.old[..], &self.new[..], self.ops())
521
+ }
522
+
523
+ /// Utility to return a unified diff formatter.
524
+ pub fn unified_diff<'diff>(&'diff self) -> UnifiedDiff<'diff, 'old, 'new, 'bufs, T> {
525
+ UnifiedDiff::from_text_diff(self)
526
+ }
527
+
528
+ /// Iterates over the changes the op expands to with inline emphasis.
529
+ ///
530
+ /// This is very similar to [`TextDiff::iter_changes`] but it performs a second
531
+ /// level diff on adjacent line replacements. The exact behavior of
532
+ /// this function with regards to how it detects those inline changes
533
+ /// is currently not defined and will likely change over time.
534
+ ///
535
+ /// This method has a hardcoded 500ms deadline which is often not ideal. For
536
+ /// fine tuning use [`iter_inline_changes_deadline`](Self::iter_inline_changes_deadline).
537
+ ///
538
+ /// As of similar 1.2.0 the behavior of this function changes depending on
539
+ /// if the `unicode` feature is enabled or not. It will prefer unicode word
540
+ /// splitting over word splitting depending on the feature flag.
541
+ ///
542
+ /// Requires the `inline` feature.
543
+ #[cfg(feature = "inline")]
544
+ pub fn iter_inline_changes<'slf>(
545
+ &'slf self,
546
+ op: &DiffOp,
547
+ ) -> impl Iterator<Item = InlineChange<'slf, T>> + 'slf
548
+ where
549
+ 'slf: 'old + 'new,
550
+ {
551
+ use crate::deadline_support::duration_to_deadline;
552
+
553
+ inline::iter_inline_changes(self, op, duration_to_deadline(Duration::from_millis(500)))
554
+ }
555
+
556
+ /// Iterates over the changes the op expands to with inline emphasis with a deadline.
557
+ ///
558
+ /// Like [`iter_inline_changes`](Self::iter_inline_changes) but with an explicit deadline.
559
+ #[cfg(feature = "inline")]
560
+ pub fn iter_inline_changes_deadline<'slf>(
561
+ &'slf self,
562
+ op: &DiffOp,
563
+ deadline: Option<Instant>,
564
+ ) -> impl Iterator<Item = InlineChange<'slf, T>> + 'slf
565
+ where
566
+ 'slf: 'old + 'new,
567
+ {
568
+ inline::iter_inline_changes(self, op, deadline)
569
+ }
570
+ }
571
+
572
+ /// Use the text differ to find `n` close matches.
573
+ ///
574
+ /// `cutoff` defines the threshold which needs to be reached for a word
575
+ /// to be considered similar. See [`TextDiff::ratio`] for more information.
576
+ ///
577
+ /// ```
578
+ /// # use similar::get_close_matches;
579
+ /// let matches = get_close_matches(
580
+ /// "appel",
581
+ /// &["ape", "apple", "peach", "puppy"][..],
582
+ /// 3,
583
+ /// 0.6
584
+ /// );
585
+ /// assert_eq!(matches, vec!["apple", "ape"]);
586
+ /// ```
587
+ ///
588
+ /// Requires the `text` feature.
589
+ pub fn get_close_matches<'a, T: DiffableStr + ?Sized>(
590
+ word: &T,
591
+ possibilities: &[&'a T],
592
+ n: usize,
593
+ cutoff: f32,
594
+ ) -> Vec<&'a T> {
595
+ let mut matches = BinaryHeap::new();
596
+ let seq1 = word.tokenize_chars();
597
+ let quick_ratio = QuickSeqRatio::new(&seq1);
598
+
599
+ for &possibility in possibilities {
600
+ let seq2 = possibility.tokenize_chars();
601
+
602
+ if upper_seq_ratio(&seq1, &seq2) < cutoff || quick_ratio.calc(&seq2) < cutoff {
603
+ continue;
604
+ }
605
+
606
+ let diff = TextDiff::from_slices(&seq1, &seq2);
607
+ let ratio = diff.ratio();
608
+ if ratio >= cutoff {
609
+ // we're putting the word itself in reverse in so that matches with
610
+ // the same ratio are ordered lexicographically.
611
+ matches.push(((ratio * u32::MAX as f32) as u32, Reverse(possibility)));
612
+ }
613
+ }
614
+
615
+ let mut rv = vec![];
616
+ for _ in 0..n {
617
+ if let Some((_, elt)) = matches.pop() {
618
+ rv.push(elt.0);
619
+ } else {
620
+ break;
621
+ }
622
+ }
623
+
624
+ rv
625
+ }
626
+
627
+ #[test]
628
+ fn test_captured_ops() {
629
+ let diff = TextDiff::from_lines(
630
+ "Hello World\nsome stuff here\nsome more stuff here\n",
631
+ "Hello World\nsome amazing stuff here\nsome more stuff here\n",
632
+ );
633
+ insta::assert_debug_snapshot!(&diff.ops());
634
+ }
635
+
636
+ #[test]
637
+ fn test_captured_word_ops() {
638
+ let diff = TextDiff::from_words(
639
+ "Hello World\nsome stuff here\nsome more stuff here\n",
640
+ "Hello World\nsome amazing stuff here\nsome more stuff here\n",
641
+ );
642
+ let changes = diff
643
+ .ops()
644
+ .iter()
645
+ .flat_map(|op| diff.iter_changes(op))
646
+ .collect::<Vec<_>>();
647
+ insta::assert_debug_snapshot!(&changes);
648
+ }
649
+
650
+ #[test]
651
+ fn test_unified_diff() {
652
+ let diff = TextDiff::from_lines(
653
+ "Hello World\nsome stuff here\nsome more stuff here\n",
654
+ "Hello World\nsome amazing stuff here\nsome more stuff here\n",
655
+ );
656
+ assert!(diff.newline_terminated());
657
+ insta::assert_snapshot!(&diff
658
+ .unified_diff()
659
+ .context_radius(3)
660
+ .header("old", "new")
661
+ .to_string());
662
+ }
663
+
664
+ #[test]
665
+ fn test_line_ops() {
666
+ let a = "Hello World\nsome stuff here\nsome more stuff here\n";
667
+ let b = "Hello World\nsome amazing stuff here\nsome more stuff here\n";
668
+ let diff = TextDiff::from_lines(a, b);
669
+ assert!(diff.newline_terminated());
670
+ let changes = diff
671
+ .ops()
672
+ .iter()
673
+ .flat_map(|op| diff.iter_changes(op))
674
+ .collect::<Vec<_>>();
675
+ insta::assert_debug_snapshot!(&changes);
676
+
677
+ #[cfg(feature = "bytes")]
678
+ {
679
+ let byte_diff = TextDiff::from_lines(a.as_bytes(), b.as_bytes());
680
+ let byte_changes = byte_diff
681
+ .ops()
682
+ .iter()
683
+ .flat_map(|op| byte_diff.iter_changes(op))
684
+ .collect::<Vec<_>>();
685
+ for (change, byte_change) in changes.iter().zip(byte_changes.iter()) {
686
+ assert_eq!(change.to_string_lossy(), byte_change.to_string_lossy());
687
+ }
688
+ }
689
+ }
690
+
691
+ #[test]
692
+ fn test_virtual_newlines() {
693
+ let diff = TextDiff::from_lines("a\nb", "a\nc\n");
694
+ assert!(diff.newline_terminated());
695
+ let changes = diff
696
+ .ops()
697
+ .iter()
698
+ .flat_map(|op| diff.iter_changes(op))
699
+ .collect::<Vec<_>>();
700
+ insta::assert_debug_snapshot!(&changes);
701
+ }
702
+
703
+ #[test]
704
+ fn test_char_diff() {
705
+ let diff = TextDiff::from_chars("Hello World", "Hallo Welt");
706
+ insta::assert_debug_snapshot!(diff.ops());
707
+
708
+ #[cfg(feature = "bytes")]
709
+ {
710
+ let byte_diff = TextDiff::from_chars("Hello World".as_bytes(), "Hallo Welt".as_bytes());
711
+ assert_eq!(diff.ops(), byte_diff.ops());
712
+ }
713
+ }
714
+
715
+ #[test]
716
+ fn test_ratio() {
717
+ let diff = TextDiff::from_chars("abcd", "bcde");
718
+ assert_eq!(diff.ratio(), 0.75);
719
+ let diff = TextDiff::from_chars("", "");
720
+ assert_eq!(diff.ratio(), 1.0);
721
+ }
722
+
723
+ #[test]
724
+ fn test_get_close_matches() {
725
+ let matches = get_close_matches("appel", &["ape", "apple", "peach", "puppy"][..], 3, 0.6);
726
+ assert_eq!(matches, vec!["apple", "ape"]);
727
+ let matches = get_close_matches(
728
+ "hulo",
729
+ &[
730
+ "hi", "hulu", "hali", "hoho", "amaz", "zulo", "blah", "hopp", "uulo", "aulo",
731
+ ][..],
732
+ 5,
733
+ 0.7,
734
+ );
735
+ assert_eq!(matches, vec!["aulo", "hulu", "uulo", "zulo"]);
736
+ }
737
+
738
+ #[test]
739
+ fn test_lifetimes_on_iter() {
740
+ use crate::Change;
741
+
742
+ fn diff_lines<'x, T>(old: &'x T, new: &'x T) -> Vec<Change<&'x T::Output>>
743
+ where
744
+ T: DiffableStrRef + ?Sized,
745
+ {
746
+ TextDiff::from_lines(old, new).iter_all_changes().collect()
747
+ }
748
+
749
+ let a = "1\n2\n3\n".to_string();
750
+ let b = "1\n99\n3\n".to_string();
751
+ let changes = diff_lines(&a, &b);
752
+ insta::assert_debug_snapshot!(&changes);
753
+ }
754
+
755
+ #[test]
756
+ #[cfg(feature = "serde")]
757
+ fn test_serde() {
758
+ let diff = TextDiff::from_lines(
759
+ "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff",
760
+ "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n",
761
+ );
762
+ let changes = diff
763
+ .ops()
764
+ .iter()
765
+ .flat_map(|op| diff.iter_changes(op))
766
+ .collect::<Vec<_>>();
767
+ let json = serde_json::to_string_pretty(&changes).unwrap();
768
+ insta::assert_snapshot!(&json);
769
+ }
770
+
771
+ #[test]
772
+ #[cfg(feature = "serde")]
773
+ fn test_serde_ops() {
774
+ let diff = TextDiff::from_lines(
775
+ "Hello World\nsome stuff here\nsome more stuff here\n\nAha stuff here\nand more stuff",
776
+ "Stuff\nHello World\nsome amazing stuff here\nsome more stuff here\n",
777
+ );
778
+ let changes = diff.ops();
779
+ let json = serde_json::to_string_pretty(&changes).unwrap();
780
+ insta::assert_snapshot!(&json);
781
+ }
782
+
783
+ #[test]
784
+ fn test_regression_issue_37() {
785
+ let config = TextDiffConfig::default();
786
+ let diff = config.diff_lines("\u{18}\n\n", "\n\n\r");
787
+ let mut output = diff.unified_diff();
788
+ assert_eq!(
789
+ output.context_radius(0).to_string(),
790
+ "@@ -1 +1,0 @@\n-\u{18}\n@@ -2,0 +2,2 @@\n+\n+\r"
791
+ );
792
+ }