LCOV - code coverage report
Current view: top level - src/formats - email.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 75.0 % 12 9
Test Date: 2026-06-16 03:31:00 Functions: - 0 0
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright 2026 The Authors
       2              : //
       3              : // Licensed under the Apache License, Version 2.0 (the "License");
       4              : // you may not use this file except in compliance with the License.
       5              : // You may obtain a copy of the License at
       6              : //
       7              : //      https://www.apache.org/licenses/LICENSE-2.0
       8              : //
       9              : // Unless required by applicable law or agreed to in writing, software
      10              : // distributed under the License is distributed on an "AS IS" BASIS,
      11              : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12              : // See the License for the specific language governing permissions and
      13              : // limitations under the License.
      14              : 
      15              : /// An email address.
      16              : ///
      17              : /// See:
      18              : ///
      19              : /// - [RFC 5321](https://www.rfc-editor.org/rfc/rfc5321.html#section-4.1.2)
      20              : /// - [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322#section-3.4.1)
      21              : class Email {
      22              :   final String localPart;
      23              :   final String domain;
      24              : 
      25            2 :   Email._({required this.localPart, required this.domain});
      26              : 
      27            0 :   @override
      28            0 :   String toString() => '$localPart@$domain';
      29              : 
      30            0 :   Uri toUri() => Uri(scheme: 'mailto', path: toString());
      31              : 
      32              :   static const _localPartRegex =
      33              :       r"(?<localPart>[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+)";
      34              : 
      35              :   static const _domainRegex =
      36              :       r"(?<domain>[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)";
      37              : 
      38              :   static const _addrSpec = '$_localPartRegex@$_domainRegex';
      39              : 
      40            6 :   static final _emailRegex = RegExp('^$_addrSpec\$');
      41              : 
      42              :   /// Parse [input], returning a valid email address.
      43              :   ///
      44              :   /// This is based on the HTML Living Standard, section 4.10.5 The input element.
      45              :   ///
      46              :   /// See: https://html.spec.whatwg.org/multipage/input.html#email-state-(type=email)
      47              :   ///
      48              :   /// The approach is a pragmatic subset of RFC 5322.
      49            2 :   static Email? tryParse(String input, {int maxInputLength = 30}) {
      50            4 :     if (input.length > maxInputLength) {
      51              :       return null;
      52              :     }
      53              : 
      54            4 :     var match = _emailRegex.firstMatch(input);
      55              :     if (match == null) {
      56              :       return null;
      57              :     }
      58            2 :     var localPart = match.namedGroup('localPart');
      59            2 :     var domain = match.namedGroup('domain');
      60              : 
      61              :     if (localPart == null || domain == null) {
      62              :       return null;
      63              :     }
      64            2 :     return Email._(localPart: localPart, domain: domain);
      65              :   }
      66              : 
      67            4 :   static bool isValid(String value) => tryParse(value) != null;
      68              : }
        

Generated by: LCOV version 2.0-1