humanname 0.5.0-x86_64-linux → 0.8.0-x86_64-linux
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.
- checksums.yaml +5 -5
- data/README.md +8 -39
- data/humanname.gemspec +5 -5
- data/lib/humanname/version.rb +1 -1
- data/lib/humanname.rb +127 -10
- data/lib/native/arm64/libhuman_name.dylib +0 -0
- data/lib/native/arm64/libhuman_name.so +0 -0
- data/lib/native/x86_64/human_name.dll +0 -0
- data/lib/native/x86_64/libhuman_name.dylib +0 -0
- data/lib/native/x86_64/libhuman_name.so +0 -0
- data/spec/humanname_spec.rb +12 -14
- metadata +18 -16
- data/lib/humanname/native.bundle +0 -0
- data/lib/humanname/native.so +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 4f09cc8706ffe6d100443c3b1424e268559eb5ad95816cf8db9a49d92f247c41
|
4
|
+
data.tar.gz: 318f6bf3ea00aa09f7c6a503182351ea491ae7854a26b96a0ac8ea9386cca4e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9c480c75130da9fbd194d500407fb5855344d4989157f133483045b461a3a1c84586217bd4242b07a8d04219f51300917b25741e2013986cf4f551158e8f036
|
7
|
+
data.tar.gz: 675a2825eaf398d8ea6dde01e8bf8d6c80b3a596e5423552720a56da1065e548bbd4f44652b246455b720e059f320990665c3eab4c49dc85e7da95dad1f62f93
|
data/README.md
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
# human-name-rb
|
2
2
|
Ruby bindings for the Rust crate [`human_name`](https://github.com/djudd/human-name), a library for parsing and comparing human names.
|
3
3
|
|
4
|
-
[](https://travis-ci.org/djudd/human-name-rb)
|
5
|
-
|
6
4
|
See the [`human_name` docs](http://djudd.github.io/human-name) for details.
|
7
5
|
|
8
6
|
# Examples
|
@@ -36,41 +34,12 @@ See the [`human_name` docs](http://djudd.github.io/human-name) for details.
|
|
36
34
|
|
37
35
|
# Supported environments
|
38
36
|
|
39
|
-
|
40
|
-
|
41
|
-
If you're willing to do a little more work, anywhere supported by [Helix](https://github.com/tildeio/helix)
|
42
|
-
and the nightly Rust compiler:
|
43
|
-
```bash
|
44
|
-
curl -s https://static.rust-lang.org/rustup.sh | sh -s -- --channel=nightly
|
45
|
-
git clone git@github.com:djudd/human-name-rb.git
|
46
|
-
cd human-name-rb
|
47
|
-
bundle exec rake
|
48
|
-
```
|
49
|
-
|
50
|
-
That will give you a .gem file in pkg/ which should work in environments similar
|
51
|
-
to the one in which it was built.
|
52
|
-
|
53
|
-
# Benchmark results
|
54
|
-
|
55
|
-
Comparing to [`people`](https://github.com/academia-edu/people), [`namae`](https://github.com/berkmancenter/namae), and [`human_name_parser`](https://github.com/abachman/human_name_parser),
|
56
|
-
on 16k real examples taken mostly from PubMed author fields:
|
57
|
-
|
58
|
-
```
|
59
|
-
$ bundle exec rake benchmark
|
60
|
-
people gem:
|
61
|
-
3.010000 0.030000 3.040000 ( 3.032075)
|
62
|
-
namae gem:
|
63
|
-
3.550000 0.080000 3.630000 ( 3.630643)
|
64
|
-
human_name_parser gem:
|
65
|
-
1.960000 0.030000 1.990000 ( 1.991358)
|
66
|
-
this gem:
|
67
|
-
0.100000 0.000000 0.100000 ( 0.107794)
|
68
|
-
```
|
69
|
-
|
70
|
-
Our implementation uses a similar strategy to `people` and `human_name_parser`
|
71
|
-
but covers significantly more edge cases, and also supports comparison.
|
72
|
-
(`human_name_parser` also covers fewer edge cases than `people`, as of December
|
73
|
-
2015, which probably explains its speed advantage.)
|
37
|
+
Linux, MacOS, and Windows, as of the versions currently supported by GitHub Actions.
|
38
|
+
x86-64 or Apple Silicon. Ruby 2.7 or later.
|
74
39
|
|
75
|
-
|
76
|
-
|
40
|
+
If you have access to another environment which is supported by the Rust compiler,
|
41
|
+
it should be relatively straightforward to fork the library and add support. You'll need
|
42
|
+
to build [`human_name`](http://github.com/djudd/human-name), copy the resulting library
|
43
|
+
from `target/release/` in that repository to `lib/native/<arch>/` in this one,
|
44
|
+
and modify `native_lib_path` appropriately. If this environment is additionally supported
|
45
|
+
by GitHub Actions, I'm also happy to accept a PR.
|
data/humanname.gemspec
CHANGED
@@ -11,10 +11,10 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = 'https://github.com/djudd/human-name-rb'
|
12
12
|
s.license = 'Apache-2.0'
|
13
13
|
s.platform = Gem::Platform::CURRENT
|
14
|
-
s.required_ruby_version = '>= 2.
|
15
|
-
s.add_runtime_dependency '
|
16
|
-
s.add_development_dependency 'rake', '~>
|
14
|
+
s.required_ruby_version = '>= 2.7.0'
|
15
|
+
s.add_runtime_dependency 'ffi', '~> 1.15.1'
|
16
|
+
s.add_development_dependency 'rake', '~> 13.0.6'
|
17
17
|
s.add_development_dependency 'rspec', '~> 3.4.0'
|
18
|
-
s.add_development_dependency 'rubygems-tasks', '~> 0.2.
|
19
|
-
s.add_development_dependency 'pry', '~> 0.
|
18
|
+
s.add_development_dependency 'rubygems-tasks', '~> 0.2.5'
|
19
|
+
s.add_development_dependency 'pry', '~> 0.14.2'
|
20
20
|
end
|
data/lib/humanname/version.rb
CHANGED
data/lib/humanname.rb
CHANGED
@@ -1,24 +1,136 @@
|
|
1
|
-
require '
|
1
|
+
require 'ffi'
|
2
2
|
require 'humanname/version'
|
3
|
-
require 'humanname/native'
|
4
3
|
|
5
4
|
module HumanName
|
6
|
-
Name = RustHumanName
|
7
|
-
|
8
5
|
UTF8 = 'UTF-8'.freeze
|
6
|
+
NAME_PARTS = %w(
|
7
|
+
surname
|
8
|
+
given_name
|
9
|
+
initials
|
10
|
+
first_initial
|
11
|
+
middle_initials
|
12
|
+
middle_names
|
13
|
+
generational_suffix
|
14
|
+
display_first_last
|
15
|
+
display_full
|
16
|
+
display_initial_surname
|
17
|
+
).freeze
|
18
|
+
|
19
|
+
class UnsupportedPlatform < StandardError
|
20
|
+
def initialize
|
21
|
+
platform = Gem::Platform.local
|
22
|
+
super("Unsupported platform: #{platform.os}-#{platform.cpu}")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Native
|
27
|
+
extend FFI::Library
|
28
|
+
|
29
|
+
def self.init!
|
30
|
+
path = native_lib_path
|
31
|
+
if File.exist?(path)
|
32
|
+
ffi_lib path
|
33
|
+
else
|
34
|
+
raise UnsupportedPlatform.new
|
35
|
+
end
|
36
|
+
|
37
|
+
attach_function :human_name_parse, [:string], :pointer
|
38
|
+
attach_function :human_name_consistent_with, [:pointer, :pointer], :bool
|
39
|
+
attach_function :human_name_hash, [:pointer], :uint64
|
40
|
+
|
41
|
+
NAME_PARTS.each do |part|
|
42
|
+
attach_function "human_name_#{part}".to_sym, [:pointer], :pointer
|
43
|
+
end
|
44
|
+
|
45
|
+
attach_function :human_name_goes_by_middle_name, [:pointer], :bool
|
46
|
+
attach_function :human_name_byte_len, [:pointer], :uint32
|
47
|
+
|
48
|
+
attach_function :human_name_free_name, [:pointer], :void
|
49
|
+
attach_function :human_name_free_string, [:pointer], :void
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.native_lib_path
|
53
|
+
platform = Gem::Platform.local
|
54
|
+
|
55
|
+
filename = case platform.os
|
56
|
+
when 'darwin'
|
57
|
+
'libhuman_name.dylib'
|
58
|
+
when 'linux'
|
59
|
+
'libhuman_name.so'
|
60
|
+
when /mswin|mingw/
|
61
|
+
'human_name.dll'
|
62
|
+
else
|
63
|
+
raise UnsupportedPlatform.new
|
64
|
+
end
|
65
|
+
|
66
|
+
cpu = platform.cpu
|
67
|
+
cpu = 'x86_64' if cpu == 'x64'
|
68
|
+
|
69
|
+
File.expand_path(
|
70
|
+
File.join('../native/', cpu, filename),
|
71
|
+
__FILE__,
|
72
|
+
)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
Native.init!
|
77
|
+
private_constant :Native
|
78
|
+
|
79
|
+
class NativeString < String
|
80
|
+
DESTRUCTOR = Native.method(:human_name_free_string)
|
81
|
+
|
82
|
+
def self.wrap(pointer)
|
83
|
+
new(pointer) unless pointer.null?
|
84
|
+
end
|
85
|
+
|
86
|
+
def initialize(pointer)
|
87
|
+
@pointer = FFI::AutoPointer.new(pointer, DESTRUCTOR)
|
88
|
+
super(@pointer.read_string.force_encoding(UTF8))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private_constant :NativeString
|
93
|
+
|
94
|
+
class Name < FFI::AutoPointer
|
95
|
+
DESTRUCTOR = Native.method(:human_name_free_name)
|
9
96
|
|
10
|
-
class Name
|
11
97
|
def self.parse(string)
|
12
98
|
string = string.encode(UTF8) unless string.encoding == UTF8
|
13
|
-
|
99
|
+
pointer = Native.human_name_parse(string)
|
100
|
+
new(pointer) unless pointer.null?
|
14
101
|
end
|
15
102
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
103
|
+
def initialize(pointer)
|
104
|
+
super(pointer, DESTRUCTOR)
|
105
|
+
end
|
106
|
+
|
107
|
+
def ==(other)
|
108
|
+
other.is_a?(Name) && Native.human_name_consistent_with(self, other)
|
109
|
+
end
|
110
|
+
alias_method :eql?, :==
|
111
|
+
|
112
|
+
def hash
|
113
|
+
Native.human_name_hash(self)
|
19
114
|
end
|
20
115
|
|
21
|
-
|
116
|
+
NAME_PARTS.each do |part|
|
117
|
+
native_method = "human_name_#{part}".to_sym
|
118
|
+
|
119
|
+
define_method part do
|
120
|
+
pointer = Native.send(native_method, self)
|
121
|
+
NativeString.wrap(pointer)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def goes_by_middle_name
|
126
|
+
Native.human_name_goes_by_middle_name(self)
|
127
|
+
end
|
128
|
+
|
129
|
+
def length
|
130
|
+
Native.human_name_byte_len(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
JSON_PARTS = %w( surname given_name first_initial middle_initials middle_names generational_suffix ).map(&:to_sym)
|
22
134
|
|
23
135
|
def as_json(options = {})
|
24
136
|
# We take an "options" argument for minimal compatibility with ActiveSupport,
|
@@ -36,6 +148,11 @@ module HumanName
|
|
36
148
|
memo
|
37
149
|
end
|
38
150
|
end
|
151
|
+
|
152
|
+
def inspect
|
153
|
+
"HumanName::Name(#{display_full})"
|
154
|
+
end
|
155
|
+
|
39
156
|
end
|
40
157
|
|
41
158
|
def self.parse(string)
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/humanname_spec.rb
CHANGED
@@ -9,7 +9,7 @@ describe HumanName do
|
|
9
9
|
expect(n.given_name).to eq('Jane')
|
10
10
|
expect(n.surname).to eq('Doe')
|
11
11
|
expect(n.middle_names).to be_nil
|
12
|
-
expect(n.
|
12
|
+
expect(n.generational_suffix).to be_nil
|
13
13
|
expect(n.display_full).to eq('Jane Doe')
|
14
14
|
expect(n.display_first_last).to eq('Jane Doe')
|
15
15
|
expect(n.display_initial_surname).to eq('J. Doe')
|
@@ -22,7 +22,7 @@ describe HumanName do
|
|
22
22
|
expect(n.given_name).to eq('John')
|
23
23
|
expect(n.surname).to eq('de la MacDonald')
|
24
24
|
expect(n.middle_names).to eq('Allen')
|
25
|
-
expect(n.
|
25
|
+
expect(n.generational_suffix).to eq('Jr.')
|
26
26
|
expect(n.display_full).to eq('John Allen Q. de la MacDonald, Jr.')
|
27
27
|
expect(n.display_first_last).to eq('John de la MacDonald')
|
28
28
|
expect(n.display_initial_surname).to eq('J. de la MacDonald')
|
@@ -69,16 +69,6 @@ describe HumanName do
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
describe 'matches_slug_or_localpart' do
|
73
|
-
it 'is true given match' do
|
74
|
-
expect(HumanName.parse("Jane Doe").matches_slug_or_localpart('janexdoe')).to be_truthy
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'is false given non-match' do
|
78
|
-
expect(HumanName.parse("Jane Doe").matches_slug_or_localpart('johnxdoe')).to be_falsey
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
72
|
it 'implements as_json' do
|
83
73
|
n = HumanName.parse("JOHN ALLEN Q DE LA MACDONALD JR")
|
84
74
|
expect(n.as_json).to eq({
|
@@ -87,11 +77,19 @@ describe HumanName do
|
|
87
77
|
middle_names: 'Allen',
|
88
78
|
first_initial: 'J',
|
89
79
|
middle_initials: 'AQ',
|
90
|
-
|
80
|
+
generational_suffix: 'Jr.',
|
91
81
|
})
|
92
82
|
end
|
93
83
|
|
94
84
|
it 'does not leak memory' do
|
85
|
+
skip unless ['linux', 'darwin'].include?(Gem::Platform.local.os)
|
86
|
+
|
87
|
+
# This is fishy but we either have a memory leak with 3.3 or something has changed
|
88
|
+
# with memory management such that it's harder to write a clean test for one.
|
89
|
+
# I suspect the latter because it's easier to understand why that would change
|
90
|
+
# between Ruby versions, but I'm not sure...
|
91
|
+
skip if RUBY_VERSION >= "3.3"
|
92
|
+
|
95
93
|
def rss
|
96
94
|
GC.start
|
97
95
|
`ps -o rss= -p #{Process.pid}`.chomp.to_i
|
@@ -106,7 +104,7 @@ describe HumanName do
|
|
106
104
|
first_initial
|
107
105
|
middle_initials
|
108
106
|
middle_names
|
109
|
-
|
107
|
+
generational_suffix
|
110
108
|
display_first_last
|
111
109
|
display_full
|
112
110
|
display_initial_surname
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: humanname
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: x86_64-linux
|
6
6
|
authors:
|
7
7
|
- David Judd
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: ffi
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 1.15.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 1.15.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 13.0.6
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 13.0.6
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,28 +58,28 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.2.
|
61
|
+
version: 0.2.5
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.2.
|
68
|
+
version: 0.2.5
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: pry
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
75
|
+
version: 0.14.2
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
82
|
+
version: 0.14.2
|
83
83
|
description: A library for parsing and comparing human names. Wraps the Rust crate
|
84
84
|
`human_name`.
|
85
85
|
email: david.a.judd@gmail.com
|
@@ -92,9 +92,12 @@ files:
|
|
92
92
|
- README.md
|
93
93
|
- humanname.gemspec
|
94
94
|
- lib/humanname.rb
|
95
|
-
- lib/humanname/native.bundle
|
96
|
-
- lib/humanname/native.so
|
97
95
|
- lib/humanname/version.rb
|
96
|
+
- lib/native/arm64/libhuman_name.dylib
|
97
|
+
- lib/native/arm64/libhuman_name.so
|
98
|
+
- lib/native/x86_64/human_name.dll
|
99
|
+
- lib/native/x86_64/libhuman_name.dylib
|
100
|
+
- lib/native/x86_64/libhuman_name.so
|
98
101
|
- spec/humanname_spec.rb
|
99
102
|
- spec/spec_helper.rb
|
100
103
|
homepage: https://github.com/djudd/human-name-rb
|
@@ -109,15 +112,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
109
112
|
requirements:
|
110
113
|
- - ">="
|
111
114
|
- !ruby/object:Gem::Version
|
112
|
-
version: 2.
|
115
|
+
version: 2.7.0
|
113
116
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
117
|
requirements:
|
115
118
|
- - ">="
|
116
119
|
- !ruby/object:Gem::Version
|
117
120
|
version: '0'
|
118
121
|
requirements: []
|
119
|
-
|
120
|
-
rubygems_version: 2.5.2
|
122
|
+
rubygems_version: 3.5.9
|
121
123
|
signing_key:
|
122
124
|
specification_version: 4
|
123
125
|
summary: A library for parsing and comparing human names
|
data/lib/humanname/native.bundle
DELETED
Binary file
|
data/lib/humanname/native.so
DELETED
Binary file
|