user/dev discussion of public-inbox itself
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [PATCH 4/4] address: pairs: new helper for JMAP (and maybe lei)
  2021-01-05  9:04  7% [PATCH 0/4] more lei usability stuff Eric Wong
@ 2021-01-05  9:04  6% ` Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2021-01-05  9:04 UTC (permalink / raw)
  To: meta

Per JMAP RFC 8621 sec 4.1.2.3, we should be able to
denote the lack of a phrase/comment corresponding to an
email address with a JSON "null" (or Perl `undef').

  [
    { "name": "James Smythe", "email": "james@example.com" },
    { "name": null, "email": "jane@example.com" },
    { "name": "John Smith", "email": "john@example.com" }
  ]

The new "pairs" method just returns a 2 dimensional array
and the consumer will fill in the field names if necessary
(or not).

lei(1) may use the two dimensional array as-is for JSON output.
---
 lib/PublicInbox/Address.pm   | 11 ++++++++++-
 lib/PublicInbox/AddressPP.pm | 21 +++++++++++++++++++++
 t/address.t                  | 33 +++++++++++++++++++++++++++------
 3 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/lib/PublicInbox/Address.pm b/lib/PublicInbox/Address.pm
index f5af4c23..a090fa43 100644
--- a/lib/PublicInbox/Address.pm
+++ b/lib/PublicInbox/Address.pm
@@ -2,7 +2,9 @@
 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
 package PublicInbox::Address;
 use strict;
-use warnings;
+use v5.10.1;
+use parent 'Exporter';
+our @EXPORT_OK = qw(pairs);
 
 sub xs_emails {
 	grep { defined } map { $_->address() } parse_email_addresses($_[0])
@@ -17,11 +19,18 @@ sub xs_names {
 	} parse_email_addresses($_[0]);
 }
 
+sub xs_pairs { # for JMAP, RFC 8621 section 4.1.2.3
+	[ map { # LHS (name) may be undef
+		[ $_->phrase // $_->comment, $_->address ]
+	} parse_email_addresses($_[0]) ];
+}
+
 eval {
 	require Email::Address::XS;
 	Email::Address::XS->import(qw(parse_email_addresses));
 	*emails = \&xs_emails;
 	*names = \&xs_names;
+	*pairs = \&xs_pairs;
 };
 
 if ($@) {
diff --git a/lib/PublicInbox/AddressPP.pm b/lib/PublicInbox/AddressPP.pm
index c04de74b..6a3ae4fe 100644
--- a/lib/PublicInbox/AddressPP.pm
+++ b/lib/PublicInbox/AddressPP.pm
@@ -13,6 +13,7 @@ sub emails {
 }
 
 sub names {
+	# split by address and post-address comment
 	my @p = split(/<?([^@<>]+)\@[\w\.\-]+>?\s*(\(.*?\))?(?:,\s*|\z)/,
 			$_[0]);
 	my @ret;
@@ -35,4 +36,24 @@ sub names {
 	@ret;
 }
 
+sub pairs { # for JMAP, RFC 8621 section 4.1.2.3
+	my ($s) = @_;
+	[ map {
+		my $addr = $_;
+		if ($s =~ s/\A\s*(.*?)\s*<\Q$addr\E>\s*(.*?)\s*(?:,|\z)// ||
+		    $s =~ s/\A\s*(.*?)\s*\Q$addr\E\s*(.*?)\s*(?:,|\z)//) {
+			my ($phrase, $comment) = ($1, $2);
+			$phrase =~ tr/\r\n\t / /s;
+			$phrase =~ s/\A['"\s]*//;
+			$phrase =~ s/['"\s]*\z//;
+			$phrase =~ s/\s*<*\s*\z//;
+			$phrase = undef if $phrase !~ /\S/;
+			$comment = ($comment =~ /\((.*?)\)/) ? $1 : undef;
+			[ $phrase // $comment, $addr ]
+		} else {
+			();
+		}
+	} emails($s) ];
+}
+
 1;
diff --git a/t/address.t b/t/address.t
index 0adcf46d..6aa94628 100644
--- a/t/address.t
+++ b/t/address.t
@@ -7,26 +7,40 @@ use_ok 'PublicInbox::Address';
 
 sub test_pkg {
 	my ($pkg) = @_;
-	my $emails = \&{"${pkg}::emails"};
-	my $names = \&{"${pkg}::names"};
+	my $emails = $pkg->can('emails');
+	my $names = $pkg->can('names');
+	my $pairs = $pkg->can('pairs');
 
 	is_deeply([qw(e@example.com e@example.org)],
 		[$emails->('User <e@example.com>, e@example.org')],
 		'address extraction works as expected');
 
+	is_deeply($pairs->('User <e@example.com>, e@example.org'),
+			[[qw(User e@example.com)], [undef, 'e@example.org']],
+		"pair extraction works ($pkg)");
+
 	is_deeply(['user@example.com'],
 		[$emails->('<user@example.com (Comment)>')],
 		'comment after domain accepted before >');
+	is_deeply($pairs->('<user@example.com (Comment)>'),
+		[[qw(Comment user@example.com)]], "comment as name ($pkg)");
 
-	my @names = $names->(
-		'User <e@e>, e@e, "John A. Doe" <j@d>, <x@x>, <y@x> (xyz), '.
-		'U Ser <u@x> (do not use)');
+	my $s = 'User <e@e>, e@e, "John A. Doe" <j@d>, <x@x>, <y@x> (xyz), '.
+		'U Ser <u@x> (do not use)';
+	my @names = $names->($s);
 	is_deeply(\@names, ['User', 'e', 'John A. Doe', 'x', 'xyz', 'U Ser'],
 		'name extraction works as expected');
+	is_deeply($pairs->($s), [ [ 'User', 'e@e' ], [ undef, 'e@e' ],
+			[ 'John A. Doe', 'j@d' ], [ undef, 'x@x' ],
+			[ 'xyz', 'y@x' ], [ 'U Ser', 'u@x' ] ],
+		"pairs extraction works for $pkg");
 
 	@names = $names->('"user@example.com" <user@example.com>');
 	is_deeply(['user'], \@names,
 		'address-as-name extraction works as expected');
+	is_deeply($pairs->('"user@example.com" <user@example.com>'),
+		[ [ 'user@example.com', 'user@example.com' ] ],
+		"pairs for $pkg");
 
 	{
 		my $backwards = 'u@example.com (John Q. Public)';
@@ -34,10 +48,17 @@ sub test_pkg {
 		is_deeply(\@names, ['John Q. Public'], 'backwards name OK');
 		my @emails = $emails->($backwards);
 		is_deeply(\@emails, ['u@example.com'], 'backwards emails OK');
+
+		is_deeply($pairs->($backwards),
+			[ [ 'John Q. Public', 'u@example.com' ] ],
+			"backwards pairs $pkg");
 	}
 
-	@names = $names->('"Quote Unneeded" <user@example.com>');
+	$s = '"Quote Unneeded" <user@example.com>';
+	@names = $names->($s);
 	is_deeply(['Quote Unneeded'], \@names, 'extra quotes dropped');
+	is_deeply($pairs->($s), [ [ 'Quote Unneeded', 'user@example.com' ] ],
+		"extra quotes dropped in pairs $pkg");
 
 	my @emails = $emails->('Local User <user>');
 	is_deeply([], \@emails , 'no address for local address');

^ permalink raw reply related	[relevance 6%]

* [PATCH 0/4] more lei usability stuff
@ 2021-01-05  9:04  7% Eric Wong
  2021-01-05  9:04  6% ` [PATCH 4/4] address: pairs: new helper for JMAP (and maybe lei) Eric Wong
  0 siblings, 1 reply; 2+ results
From: Eric Wong @ 2021-01-05  9:04 UTC (permalink / raw)
  To: meta

Eric Wong (4):
  lei: completion: fix filename completion
  lei: automatic pager support
  lei: use client env as-is, drop daemon-env command
  address: pairs: new helper for JMAP (and maybe lei)

 contrib/completion/lei-completion.bash |  2 +-
 lib/PublicInbox/Address.pm             | 11 ++++-
 lib/PublicInbox/AddressPP.pm           | 21 ++++++++
 lib/PublicInbox/LEI.pm                 | 68 +++++++++++++++-----------
 t/address.t                            | 33 ++++++++++---
 t/lei.t                                | 30 +-----------
 6 files changed, 100 insertions(+), 65 deletions(-)

^ permalink raw reply	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2021-01-05  9:04  7% [PATCH 0/4] more lei usability stuff Eric Wong
2021-01-05  9:04  6% ` [PATCH 4/4] address: pairs: new helper for JMAP (and maybe lei) Eric Wong

Code repositories for project(s) associated with this public inbox

	https://80x24.org/public-inbox.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).