CINXE.COM
Attachment 9002232 Details for Bug 1454764 – Format mozilla-central with rustfmt 1.0 RC. v1
<!doctype html> <html lang="en"> <head> <base href="https://bugzilla.mozilla.org/attachment.cgi?id=9002232&action=edit"> <meta charset="UTF-8"> <meta property="og:type" content="website"> <meta property="og:title" content=" Attachment 9002232 Details for Bug 1454764 – Format mozilla-central with rustfmt 1.0 RC. v1"> <meta name="viewport" content="width=1024"> <meta name="color-scheme" content="dark light"> <meta name="generator" content="Bugzilla 20241126.1"> <meta name="bugzilla-global" content="dummy" id="bugzilla-global" data-bugzilla="{"api_token":"","config":{"basepath":"\/"},"constant":{"COMMENT_COLS":80},"param":{"maxattachmentsize":"10240","maxusermatches":"50","splinter_base":"\/page.cgi?id=splinter.html&ignore=\/","use_markdown":"1"},"string":{"TextEditor":{"command_bold":"Bold","command_bulleted_list":"Bulleted list","command_code":"Code","command_heading":"Heading","command_italic":"Italic","command_link":"Link","command_numbered_list":"Numbered list","command_quote":"Quote","comment_editor":"Comment Editor","edit":"Edit","etiquette_link":{"href":"page.cgi?id=etiquette.html","text":"Etiquette"},"guidelines_link":{"href":"page.cgi?id=bug-writing.html","text":"Bug Writing Guidelines"},"loading":"Loading…","markdown_link":{"href":"https:\/\/guides.github.com\/features\/mastering-markdown\/","text":"Markdown supported"},"preview":"Preview","preview_error":"Preview could not be loaded. Please try again later.","text_editor":"Text Editor","toolbar_label":"Markdown text-formatting toolbar"},"bug":"bug","bug_type_required":"You must select a Type for this bug","component_required":"You must select a Component for this bug","description_required":"You must enter a Description for this bug","short_desc_required":"You must enter a Summary for this bug","version_required":"You must select a Version for this bug"},"user":{"is_new":true,"login":""}}"> <meta name="google-site-verification" content="JYXIuR9cAlV7fLmglSrc_4UaJS6Wzh5Mdxiorqu5AQc"> <title> Attachment 9002232 Details for Bug 1454764 – Format mozilla-central with rustfmt 1.0 RC. v1</title> <link href="/static/v20241126.1/skins/standard/global.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/standard/attachment.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/js/jquery/ui/jquery-ui-min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/js/jquery/ui/jquery-ui-structure-min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/js/jquery/ui/jquery-ui-theme-min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/lib/prism.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/extensions/Needinfo/web/styles/needinfo.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/extensions/Review/web/styles/badge.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/extensions/Review/web/styles/review.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/standard/text-editor.css" rel="stylesheet" type="text/css"> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/jquery/jquery-min.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/jquery/ui/jquery-ui-min.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/jquery/plugins/devbridgeAutocomplete/devbridgeAutocomplete-min.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/global.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/util.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/widgets.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH">BUGZILLA.value_descs = JSON.parse('{\"bug_status\":{},\"resolution\":{\"\":\"---\"}}'); review_suggestions = { _mentors: [ ], 'Lint and Formatting': [ ], _end: 1 }; static_component = 'Lint and Formatting'; </script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/text-editor.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/attachment.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/field.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/lib/prism.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/extensions/GoogleAnalytics/web/js/analytics.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/js/lib/md5.min.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/extensions/Review/web/js/badge.js"></script> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/extensions/Review/web/js/review.js"></script> <link href="/static/v20241126.1/skins/lib/fontawesome.min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/lib/fontawesome-brands.min.css" rel="stylesheet" type="text/css"> <link href="/static/v20241126.1/skins/lib/fontawesome-solid.min.css" rel="stylesheet" type="text/css"> <link rel="search" type="application/opensearchdescription+xml" title="Bugzilla@Mozilla" href="/search_plugin.cgi"> <link rel="shortcut icon" href="/extensions/BMO/web/images/favicon.ico"> <meta name="google-analytics" content="UA-36116321-3" data-location="https://bugzilla.mozilla.org/attachment/edit" data-title="Attachment 9002232 Details for Bug 1454764 &ndash; Format mozilla-central with rustfmt 1.0 RC. v1"> <script async src="https://www.google-analytics.com/analytics.js"></script> <meta name="robots" content="noarchive"> <meta http-equiv="X-Translated-By" content="Google"> <meta http-equiv="X-Translated-To" content="iw"> <script type="text/javascript" src="https://www.gstatic.com/_/translate_http/_/js/k=translate_http.tr.en_GB.omlEigW4xY8.O/am=DgY/d=1/rs=AN8SPfpjsL9kUWY0h-sp7Ilu7hZWGwEmeg/m=corsproxy" data-sourceurl="https://bugzilla.mozilla.org/attachment.cgi?id=9002232&action=edit"></script> <link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" rel="stylesheet"> <script type="text/javascript" src="https://www.gstatic.com/_/translate_http/_/js/k=translate_http.tr.en_GB.omlEigW4xY8.O/am=DgY/d=1/exm=corsproxy/ed=1/rs=AN8SPfpjsL9kUWY0h-sp7Ilu7hZWGwEmeg/m=phishing_protection" data-phishing-protection-enabled="false" data-forms-warning-enabled="true" data-source-url="https://bugzilla.mozilla.org/attachment.cgi?id=9002232&action=edit"></script> <meta name="robots" content="none"> </head> <body class="bugzilla-mozilla-org skin-standard no_javascript"> <script type="text/javascript" src="https://www.gstatic.com/_/translate_http/_/js/k=translate_http.tr.en_GB.omlEigW4xY8.O/am=DgY/d=1/exm=corsproxy,phishing_protection/ed=1/rs=AN8SPfpjsL9kUWY0h-sp7Ilu7hZWGwEmeg/m=navigationui" data-environment="prod" data-proxy-url="https://bugzilla-mozilla-org.translate.goog" data-proxy-full-url="https://bugzilla-mozilla-org.translate.goog/attachment.cgi?id=9002232&action=edit&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" data-source-url="https://bugzilla.mozilla.org/attachment.cgi?id=9002232&action=edit" data-source-language="pl" data-target-language="iw" data-display-language="en-GB" data-detected-source-language="" data-is-source-untranslated="false" data-source-untranslated-url="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://bugzilla.mozilla.org/attachment.cgi?id%3D9002232%26action%3Dedit&anno=2" data-client="tr"></script> <div id="wrapper"> <header id="header" role="banner" aria-label="Global Header"> <div class="inner" role="none"><button type="button" class="iconic ghost" id="open-menu-drawer" aria-label="Open Site Menu"> <span class="icon" aria-hidden="true" data-icon="menu"></span> </button> <div id="header-external-links" class="dropdown" role="none"><button type="button" id="header-external-menu-button" class="dropdown-button minor" aria-label="Show Mozilla Menu" aria-expanded="false" aria-haspopup="true" aria-controls="header-external-menu"> <img src="/static/v20241126.1/extensions/BMO/web/images/moz-fav-one-color-white-rgb.svg" width="32" height="32" alt=""> </button> <ul class="dropdown-content right" id="header-external-menu" role="menu" aria-label="Mozilla Menu" style="display:none;"> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://www.mozilla.org/" role="menuitem"> <span class="label" role="none">Mozilla Home</span> </a></li> <li role="separator"></li> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://www.mozilla.org/privacy/websites/" role="menuitem"> <span class="label" role="none">Privacy</span> </a></li> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://www.mozilla.org/privacy/websites/%23cookies" role="menuitem"> <span class="label" role="none">Cookies</span> </a></li> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://www.mozilla.org/about/legal/" role="menuitem"> <span class="label" role="none">Legal</span> </a></li> </ul> </div> <h1 id="header-title" class="title" role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/home?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="Go to home page"> <span aria-label="Go to Bugzilla Home Page">Bugzilla</span> </a></h1> <form id="header-search" class="quicksearch" action="/buglist.cgi" data-no-csrf role="search" aria-label="Search Bugs"><button type="button" class="iconic ghost" id="show-searchbox" aria-label="Search Bugs"> <span class="icon" aria-hidden="true" data-icon="search"></span> </button> <div class="searchbox-outer dropdown" role="combobox" aria-label="Quick Search" aria-haspopup="listbox" aria-owns="header-search-dropdown" aria-expanded="false"><span class="icon" aria-hidden="true" data-icon="search"></span> <input id="quicksearch_top" class="dropdown-button" name="quicksearch" autocomplete="off" value="" accesskey="s" placeholder="Search Bugs" title="Enter a bug number or some search terms" role="searchbox" aria-controls="header-search-dropdown" aria-label="Search Terms"> <div id="header-search-dropdown" class="dropdown-content dropdown-panel right" role="listbox" style="display: none;"> <div id="header-search-dropdown-wrapper" role="none"> <section id="header-search-dropdown-help" role="group" aria-label="Help"> <footer role="none"><a href="https://bugzilla-mozilla-org.translate.goog/page.cgi?id=quicksearch.html&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Quick Search Tips</a> <a href="https://bugzilla-mozilla-org.translate.goog/query.cgi?format=advanced&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Advanced Search</a> </footer> </section> </div> </div> </div> </form> <nav id="header-nav" role="menubar" aria-label="Site Links"> <ul class="links" role="none"> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/describecomponents.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="Browse bugs by component" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="category"></span> <span class="label" role="none">Browse</span> </a></li> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/query.cgi?format=advanced&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="Search bugs using various criteria" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="pageview"></span> <span class="label" role="none">Advanced Search</span> </a></li> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/enter_bug.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="File a new bug" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="add_box"></span> <span class="label" role="none">New Bug</span> </a></li> </ul> <div class="dropdown" role="none"><button type="button" id="header-tools-menu-button" class="header-button dropdown-button minor" title="More tools…" role="menuitem" aria-label="Show More Tools Menu" aria-expanded="false" aria-haspopup="true" aria-controls="header-tools-menu"> <span class="icon" aria-hidden="true" data-icon="more_horiz"></span> </button> <ul class="dropdown-content left" id="header-tools-menu" role="menu" aria-label="More Tools Menu" style="display:none;"> <li role="none"><a href="https://bugzilla-mozilla-org.translate.goog/report.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="analytics"></span> <span class="label" role="none">Reports</span> </a></li> <li role="separator"></li> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://bmo.readthedocs.io/en/latest/" target="_blank" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="help"></span> <span class="label" role="none">Documentation</span> </a></li> </ul> </div> </nav> <ul id="header-login" class="links" role="none"> <li id="mini_login_container_top" role="none"><a id="login_link_top" href="https://bugzilla-mozilla-org.translate.goog/index.cgi?GoAheadAndLogIn=1&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" class="show_mini_login_form header-button" data-qs-suffix="_top" role="button"> <span class="icon" aria-hidden="true" data-icon="login"></span> <span class="label" role="none">Log In</span> </a> <div id="mini_login_top" class="mini-popup mini_login bz_default_hidden"> <form method="post" action="/github.cgi"><input type="hidden" name="github_token" value="ExYOp1LwQkaSzG3LU5Y6M5SdHzE3GZ1ar1a1DYiGmithi2E2pMhPc2jVoV41865TDMWl6aoSXqfjW58ndgdqrf6nkDnpKCcXvCCiucseYBvu4x1XPjDYvP95S2YFwd0oCwvF7AZkHUQE8oCWtXbJTDgHqCy1SeitnvsvNGy4BQUDysnyNXrGXo9cZPsxpkRtQpiqWHPeBKO8tQarVc5ufsLjFFAtWHGByqe7L90hDROmXcYYHlRmf5aXxzxoA7m3"> <input type="hidden" name="target_uri" value="https://bugzilla.mozilla.org/attachment.cgi"> <button type="submit"> <i class="fab fa-github"></i> Log In with GitHub </button> </form> <div class="method-separator"> or </div> <form action="/attachment.cgi?id=9002232&action=edit" method="POST" data-qs-suffix="_top"><input id="Bugzilla_login_top" class="bz_login" name="Bugzilla_login" title="Login" placeholder="Email" aria-label="Email" type="email" required> <input class="bz_password" id="Bugzilla_password_top" name="Bugzilla_password" type="password" title="Password" placeholder="Password" aria-label="Password" required> <input class="bz_password bz_default_hidden bz_mini_login_help" type="text" id="Bugzilla_password_dummy_top" value="password" title="Password"> <span class="remember-outer"> <input type="checkbox" id="Bugzilla_remember_top" name="Bugzilla_remember" value="on" class="bz_remember" checked> <label for="Bugzilla_remember_top">Remember me</label> </span> <input type="hidden" name="Bugzilla_login_token" value="1732794690-KBboSz8B6c8ifGe1tEZLbS24hTNsSM8tPVgWvaIk8TY"> <input type="submit" name="GoAheadAndLogIn" value="Log In" id="log_in_top" class="check_mini_login_fields" data-qs-suffix="_top"> <a href="https://bugzilla-mozilla-org.translate.goog/attachment.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB#" id="hide_mini_login_top" aria-label="Close" class="close-button hide_mini_login_form" data-qs-suffix="_top"> <span class="icon" aria-hidden="true"></span> </a> </form> <div class="footer"><a href="https://bugzilla-mozilla-org.translate.goog/createaccount.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Create an Account</a> · <a id="forgot_link_top" href="https://bugzilla-mozilla-org.translate.goog/index.cgi?GoAheadAndLogIn=1&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB#forgot" class="show_forgot_form" data-qs-suffix="_top">Forgot Password</a> </div> </div> <div id="forgot_form_top" class="mini-popup mini_forgot bz_default_hidden"> <form action="/token.cgi" method="post"><input type="email" name="loginname" size="20" placeholder="Email" aria-label="Email" required> <input id="forgot_button_top" value="Reset Password" type="submit"> <input type="hidden" name="a" value="reqpw"> <input type="hidden" id="token_top" name="token" value="1732794690-Z4fJ8KYk_yZdDbBCdCrPko40AzjAJBj29-65ZdIRQYM"> <a href="https://bugzilla-mozilla-org.translate.goog/attachment.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB#" class="close-button hide_forgot_form" aria-label="Close" data-qs-suffix="_top"> <span class="icon" aria-hidden="true"></span> </a> </form> </div></li> </ul> </div><dialog id="menu-drawer" inert aria-label="Site Menu"> <div class="drawer-inner" role="none"> <div class="header" role="none"><button type="button" class="iconic ghost" id="close-menu-drawer" aria-label="Close Site Menu"> <span class="icon" aria-hidden="true" data-icon="close"></span> </button> </div> <ul role="menu" aria-label="Site Links"> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/describecomponents.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="Browse bugs by component" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="category"></span> <span class="label" role="none">Browse</span> </a></li> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/query.cgi?format=advanced&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="Search bugs using various criteria" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="pageview"></span> <span class="label" role="none">Advanced Search</span> </a></li> <li role="none"><a class="header-button" href="https://bugzilla-mozilla-org.translate.goog/enter_bug.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" title="File a new bug" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="add_box"></span> <span class="label" role="none">New Bug</span> </a></li> <li role="none"><a href="https://bugzilla-mozilla-org.translate.goog/report.cgi?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="analytics"></span> <span class="label" role="none">Reports</span> </a></li> <li role="separator"></li> <li role="none"><a href="https://translate.google.com/website?sl=pl&tl=iw&hl=en-GB&u=https://bmo.readthedocs.io/en/latest/" target="_blank" role="menuitem"> <span class="icon" aria-hidden="true" data-icon="help"></span> <span class="label" role="none">Documentation</span> </a></li> </ul> </div> </dialog> </header> <main id="bugzilla-body" tabindex="-1"> <aside id="message-container" role="complementary"> <noscript> <div class="noscript"> <div class="inner"> <p>Please enable JavaScript in your browser to use all the features on this site.</p> </div> </div> </noscript> </aside> <div id="main-inner"> <h2>Attachment 9002232 Details for <a class="bz_bug_link bz_status_REOPENED" title="REOPENED - [meta] rustfmt mozilla-central" href="https://bugzilla-mozilla-org.translate.goog/show_bug.cgi?id=1454764&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Bug 1454764</a></h2> <form method="post" action="/attachment.cgi" onsubmit="normalizeComments();"><input type="hidden" name="bugid" value="1454764"> <input type="hidden" name="id" value="9002232"> <input type="hidden" name="action" value="update"> <input type="hidden" name="contenttypemethod" value="manual"> <input type="hidden" name="delta_ts" value="2020-04-25 09:38:03"> <div id="attachment_info" class="attachment_info read"> <div id="attachment_attributes"> <div id="attachment_information_read_only" class=""> <div class="title"> [patch] <span class="bz_obsolete" title="obsolete">Format mozilla-central with rustfmt 1.0 RC. v1 </span> </div> <div class="details"> Bug-1454764---Format-mozilla-central-with-rustfmt-.patch (text/plain), 2.33 MB, created by <span class="vcard vcard_313730"><span class="fn">Bobby Holley (:bholley)</span> </span> </div> </div> <div id="attachment_information_edit"><span class="bz_hide"> (<a href="javascript:toggle_attachment_details_visibility();?_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">hide</a>) </span> <div id="attachment_description"><label for="description">Description:</label> <textarea name="description" id="description" class="block bz_hidden_option" wrap="soft" rows="3" cols="25">Format mozilla-central with rustfmt 1.0 RC. v1</textarea> </div> <div id="attachment_filename"><label for="filename">Filename:</label> <input type="text" size="20" class="text block bz_hidden_option" id="filename" name="filename" value="Bug-1454764---Format-mozilla-central-with-rustfmt-.patch"> </div> <div id="attachment_mimetype"><label for="contenttypeentry">MIME Type:</label> <input type="text" size="20" class="text block bz_hidden_option" id="contenttypeentry" name="contenttypeentry" value="text/plain"> </div> <div id="attachment_creator"><span class="label">Creator:</span> <span class="vcard vcard_313730"><span class="fn">Bobby Holley (:bholley)</span> </span> </div> <div id="attachment_size"><span class="label">Size:</span> 2.33 MB </div> <div id="attachment_ispatch"><input type="checkbox" id="ispatch" name="ispatch" value="1" checked> <label for="ispatch">patch</label> </div> <div class="readonly"> <div class="checkboxes"> <div id="attachment_isobsolete"><input type="checkbox" id="isobsolete" name="isobsolete" value="1" checked> <label for="isobsolete">obsolete</label> </div> </div> </div> </div> <div id="attachment_view_window"> <div><input type="hidden" name="markdown_off" value="0"><textarea name="comment" id="editFrame" class="bz_default_hidden" wrap="soft" disabled rows="10" cols="80">># HG changeset patch ># User Bobby Holley <bobbyholley@gmail.com> > >Bug 1454764 - Format mozilla-central with rustfmt 1.0 RC. v1 > >`cargo +nightly fmt --version` => rustfmt 0.99.2-nightly (5c9a2b6c 2018-08-07) > >Command: > >cargo +nightly fmt; pushd servo/components; for file in *; do pushd $file; cargo +nightly fmt; popd; done; popd; > >This currently excludes geckolib because of [1]. It also excludes webrender because that's effectively vendored code (we should format upstream at some point down the line). > >[1] https://github.com/rust-lang-nursery/rustfmt/issues/2936 > >MozReview-Commit-ID: CRdDMOGExMQ > >diff --git a/dom/media/gtest/hello.rs b/dom/media/gtest/hello.rs >index cd111882ae87..af1308eee6c0 100644 >--- a/dom/media/gtest/hello.rs >+++ b/dom/media/gtest/hello.rs >@@ -1,6 +1,6 @@ > #[no_mangle] >-pub extern fn test_rust() -> *const u8 { >+pub extern "C" fn test_rust() -> *const u8 { > // NB: rust &str aren't null terminated. > let greeting = "hello from rust.\0"; > greeting.as_ptr() > } >diff --git a/intl/encoding_glue/src/lib.rs b/intl/encoding_glue/src/lib.rs >index 66b627261cb9..4c35ec6ec4f2 100644 >--- a/intl/encoding_glue/src/lib.rs >+++ b/intl/encoding_glue/src/lib.rs >@@ -26,93 +26,118 @@ const NS_CSTRING_OVERHEAD: usize = 9; > > /// Takes `Option<usize>`, the destination string and a value > /// to return on failure and tries to set the length of the > /// destination string to the `usize` wrapped in the first > /// argument. > macro_rules! try_dst_set_len { > ($needed:expr, > $dst:ident, >- $ret:expr) => ( >- let needed = match $needed { >- Some(max) => { >- // XPCOM strings use uint32_t for length. >- if max > ::std::u32::MAX as usize { >+ $ret:expr) => { >+ let needed = match $needed { >+ Some(max) => { >+ // XPCOM strings use uint32_t for length. >+ if max > ::std::u32::MAX as usize { >+ return $ret; >+ } >+ max as u32 >+ } >+ None => { >+ return $ret; >+ } >+ }; >+ unsafe { >+ if $dst.fallible_set_length(needed).is_err() { > return $ret; > } >- max as u32 >- } >- None => { >- return $ret; > } > }; >- unsafe { >- if $dst.fallible_set_length(needed).is_err() { >- return $ret; >- } >- } >- ) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring(encoding: *mut *const Encoding, >- src: *const u8, >- src_len: usize, >- dst: *mut nsAString) >- -> nsresult { >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring( >+ encoding: *mut *const Encoding, >+ src: *const u8, >+ src_len: usize, >+ dst: *mut nsAString, >+) -> nsresult { > let (rv, enc) = decode_to_nsstring(&**encoding, slice::from_raw_parts(src, src_len), &mut *dst); > *encoding = enc as *const Encoding; > rv > } > >-pub fn decode_to_nsstring(encoding: &'static Encoding, >- src: &[u8], >- dst: &mut nsAString) >- -> (nsresult, &'static Encoding) { >+pub fn decode_to_nsstring( >+ encoding: &'static Encoding, >+ src: &[u8], >+ dst: &mut nsAString, >+) -> (nsresult, &'static Encoding) { > if let Some((enc, bom_length)) = Encoding::for_bom(src) { >- return (decode_to_nsstring_without_bom_handling(enc, &src[bom_length..], dst), enc); >+ return ( >+ decode_to_nsstring_without_bom_handling(enc, &src[bom_length..], dst), >+ enc, >+ ); > } >- (decode_to_nsstring_without_bom_handling(encoding, src, dst), encoding) >+ ( >+ decode_to_nsstring_without_bom_handling(encoding, src, dst), >+ encoding, >+ ) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_with_bom_removal(encoding: *const Encoding, src: *const u8, src_len: usize, dst: *mut nsAString) -> nsresult{ >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_with_bom_removal( >+ encoding: *const Encoding, >+ src: *const u8, >+ src_len: usize, >+ dst: *mut nsAString, >+) -> nsresult { > decode_to_nsstring_with_bom_removal(&*encoding, slice::from_raw_parts(src, src_len), &mut *dst) > } > >-pub fn decode_to_nsstring_with_bom_removal(encoding: &'static Encoding, >- src: &[u8], >- dst: &mut nsAString) >- -> nsresult { >+pub fn decode_to_nsstring_with_bom_removal( >+ encoding: &'static Encoding, >+ src: &[u8], >+ dst: &mut nsAString, >+) -> nsresult { > let without_bom = if encoding == UTF_8 && src.starts_with(b"\xEF\xBB\xBF") { > &src[3..] >- } else if (encoding == UTF_16LE && src.starts_with(b"\xFF\xFE")) || >- (encoding == UTF_16BE && src.starts_with(b"\xFE\xFF")) { >+ } else if (encoding == UTF_16LE && src.starts_with(b"\xFF\xFE")) >+ || (encoding == UTF_16BE && src.starts_with(b"\xFE\xFF")) >+ { > &src[2..] > } else { > src > }; > decode_to_nsstring_without_bom_handling(encoding, without_bom, dst) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_without_bom_handling(encoding: *const Encoding, src: *const u8, src_len: usize, dst: *mut nsAString) -> nsresult{ >- decode_to_nsstring_without_bom_handling(&*encoding, >- slice::from_raw_parts(src, src_len), >- &mut *dst) >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_without_bom_handling( >+ encoding: *const Encoding, >+ src: *const u8, >+ src_len: usize, >+ dst: *mut nsAString, >+) -> nsresult { >+ decode_to_nsstring_without_bom_handling( >+ &*encoding, >+ slice::from_raw_parts(src, src_len), >+ &mut *dst, >+ ) > } > >-pub fn decode_to_nsstring_without_bom_handling(encoding: &'static Encoding, >- src: &[u8], >- dst: &mut nsAString) >- -> nsresult { >+pub fn decode_to_nsstring_without_bom_handling( >+ encoding: &'static Encoding, >+ src: &[u8], >+ dst: &mut nsAString, >+) -> nsresult { > let mut decoder = encoding.new_decoder_without_bom_handling(); >- try_dst_set_len!(decoder.max_utf16_buffer_length(src.len()), >- dst, >- NS_ERROR_OUT_OF_MEMORY); >+ try_dst_set_len!( >+ decoder.max_utf16_buffer_length(src.len()), >+ dst, >+ NS_ERROR_OUT_OF_MEMORY >+ ); > // to_mut() shouldn't fail right after setting length. > let (result, read, written, had_errors) = decoder.decode_to_utf16(src, dst.to_mut(), true); > debug_assert_eq!(result, CoderResult::InputEmpty); > debug_assert_eq!(read, src.len()); > debug_assert!(written <= dst.len()); > unsafe { > if dst.fallible_set_length(written as u32).is_err() { > return NS_ERROR_OUT_OF_MEMORY; >@@ -120,36 +145,43 @@ pub fn decode_to_nsstring_without_bom_handling(encoding: &'static Encoding, > } > if had_errors { > return NS_OK_HAD_REPLACEMENTS; > } > NS_OK > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_without_bom_handling_and_without_replacement >- (encoding: *const Encoding, >- src: *const u8, >- src_len: usize, >- dst: *mut nsAString) >- -> nsresult { >- decode_to_nsstring_without_bom_handling_and_without_replacement(&*encoding, >- slice::from_raw_parts(src, >- src_len), >- &mut *dst) >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nsstring_without_bom_handling_and_without_replacement( >+ encoding: *const Encoding, >+ src: *const u8, >+ src_len: usize, >+ dst: *mut nsAString, >+) -> nsresult { >+ decode_to_nsstring_without_bom_handling_and_without_replacement( >+ &*encoding, >+ slice::from_raw_parts(src, src_len), >+ &mut *dst, >+ ) > } > >-pub fn decode_to_nsstring_without_bom_handling_and_without_replacement(encoding: &'static Encoding, src: &[u8], dst: &mut nsAString) -> nsresult{ >+pub fn decode_to_nsstring_without_bom_handling_and_without_replacement( >+ encoding: &'static Encoding, >+ src: &[u8], >+ dst: &mut nsAString, >+) -> nsresult { > let mut decoder = encoding.new_decoder_without_bom_handling(); >- try_dst_set_len!(decoder.max_utf16_buffer_length(src.len()), >- dst, >- NS_ERROR_OUT_OF_MEMORY); >+ try_dst_set_len!( >+ decoder.max_utf16_buffer_length(src.len()), >+ dst, >+ NS_ERROR_OUT_OF_MEMORY >+ ); > // to_mut() shouldn't fail right after setting length. >- let (result, read, written) = decoder >- .decode_to_utf16_without_replacement(src, dst.to_mut(), true); >+ let (result, read, written) = >+ decoder.decode_to_utf16_without_replacement(src, dst.to_mut(), true); > match result { > DecoderResult::InputEmpty => { > debug_assert_eq!(read, src.len()); > debug_assert!(written <= dst.len()); > unsafe { > if dst.fallible_set_length(written as u32).is_err() { > return NS_ERROR_OUT_OF_MEMORY; > } >@@ -160,44 +192,49 @@ pub fn decode_to_nsstring_without_bom_handling_and_without_replacement(encoding: > dst.truncate(); > NS_ERROR_UDEC_ILLEGALINPUT > } > DecoderResult::OutputFull => unreachable!(), > } > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_encode_from_utf16(encoding: *mut *const Encoding, >- src: *const u16, >- src_len: usize, >- dst: *mut nsACString) >- -> nsresult { >+pub unsafe extern "C" fn mozilla_encoding_encode_from_utf16( >+ encoding: *mut *const Encoding, >+ src: *const u16, >+ src_len: usize, >+ dst: *mut nsACString, >+) -> nsresult { > let (rv, enc) = encode_from_utf16(&**encoding, slice::from_raw_parts(src, src_len), &mut *dst); > *encoding = enc as *const Encoding; > rv > } > >-pub fn encode_from_utf16(encoding: &'static Encoding, >- src: &[u16], >- dst: &mut nsACString) >- -> (nsresult, &'static Encoding) { >+pub fn encode_from_utf16( >+ encoding: &'static Encoding, >+ src: &[u16], >+ dst: &mut nsACString, >+) -> (nsresult, &'static Encoding) { > let output_encoding = encoding.output_encoding(); > let mut encoder = output_encoding.new_encoder(); >- try_dst_set_len!(encoder.max_buffer_length_from_utf16_if_no_unmappables(src.len()), >- dst, >- (NS_ERROR_OUT_OF_MEMORY, output_encoding)); >+ try_dst_set_len!( >+ encoder.max_buffer_length_from_utf16_if_no_unmappables(src.len()), >+ dst, >+ (NS_ERROR_OUT_OF_MEMORY, output_encoding) >+ ); > > let mut total_read = 0; > let mut total_written = 0; > let mut total_had_errors = false; > loop { >- let (result, read, written, had_errors) = encoder >- .encode_from_utf16(&src[total_read..], >- &mut (dst.to_mut())[total_written..], >- true); >+ let (result, read, written, had_errors) = encoder.encode_from_utf16( >+ &src[total_read..], >+ &mut (dst.to_mut())[total_written..], >+ true, >+ ); > total_read += read; > total_written += written; > total_had_errors |= had_errors; > match result { > CoderResult::InputEmpty => { > debug_assert_eq!(total_read, src.len()); > debug_assert!(total_written <= dst.len()); > unsafe { >@@ -206,20 +243,20 @@ pub fn encode_from_utf16(encoding: &'static Encoding, > } > } > if total_had_errors { > return (NS_OK_HAD_REPLACEMENTS, output_encoding); > } > return (NS_OK, output_encoding); > } > CoderResult::OutputFull => { >- if let Some(needed) = >- checked_add(total_written, >- encoder.max_buffer_length_from_utf16_if_no_unmappables(src.len() - >- total_read)) { >+ if let Some(needed) = checked_add( >+ total_written, >+ encoder.max_buffer_length_from_utf16_if_no_unmappables(src.len() - total_read), >+ ) { > // Let's round the allocation up in order to avoid repeated > // allocations. Using power-of-two as the approximation of > // available jemalloc buckets, since linking with > // malloc_good_size is messy. > if let Some(with_bookkeeping) = NS_CSTRING_OVERHEAD.checked_add(needed) { > let rounded = with_bookkeeping.next_power_of_two(); > let unclowned = rounded - NS_CSTRING_OVERHEAD; > // XPCOM strings use uint32_t for length. >@@ -234,71 +271,86 @@ pub fn encode_from_utf16(encoding: &'static Encoding, > } > return (NS_ERROR_OUT_OF_MEMORY, output_encoding); > } > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring(encoding: *mut *const Encoding, >- src: *const nsACString, >- dst: *mut nsACString) >- -> nsresult { >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring( >+ encoding: *mut *const Encoding, >+ src: *const nsACString, >+ dst: *mut nsACString, >+) -> nsresult { > debug_assert_ne!(src as usize, dst as usize); > let (rv, enc) = decode_to_nscstring(&**encoding, &*src, &mut *dst); > *encoding = enc as *const Encoding; > rv > } > >-pub fn decode_to_nscstring(encoding: &'static Encoding, >- src: &nsACString, >- dst: &mut nsACString) >- -> (nsresult, &'static Encoding) { >+pub fn decode_to_nscstring( >+ encoding: &'static Encoding, >+ src: &nsACString, >+ dst: &mut nsACString, >+) -> (nsresult, &'static Encoding) { > if let Some((enc, bom_length)) = Encoding::for_bom(src) { >- return (decode_from_slice_to_nscstring_without_bom_handling(enc, >- &src[bom_length..], >- dst, >- 0), >- enc); >+ return ( >+ decode_from_slice_to_nscstring_without_bom_handling(enc, &src[bom_length..], dst, 0), >+ enc, >+ ); > } >- (decode_to_nscstring_without_bom_handling(encoding, src, dst), encoding) >+ ( >+ decode_to_nscstring_without_bom_handling(encoding, src, dst), >+ encoding, >+ ) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_with_bom_removal(encoding: *const Encoding, src: *const nsACString, dst: *mut nsACString) -> nsresult{ >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_with_bom_removal( >+ encoding: *const Encoding, >+ src: *const nsACString, >+ dst: *mut nsACString, >+) -> nsresult { > debug_assert_ne!(src as usize, dst as usize); > decode_to_nscstring_with_bom_removal(&*encoding, &*src, &mut *dst) > } > >-pub fn decode_to_nscstring_with_bom_removal(encoding: &'static Encoding, >- src: &nsACString, >- dst: &mut nsACString) >- -> nsresult { >+pub fn decode_to_nscstring_with_bom_removal( >+ encoding: &'static Encoding, >+ src: &nsACString, >+ dst: &mut nsACString, >+) -> nsresult { > let without_bom = if encoding == UTF_8 && src.starts_with(b"\xEF\xBB\xBF") { > &src[3..] >- } else if (encoding == UTF_16LE && src.starts_with(b"\xFF\xFE")) || >- (encoding == UTF_16BE && src.starts_with(b"\xFE\xFF")) { >+ } else if (encoding == UTF_16LE && src.starts_with(b"\xFF\xFE")) >+ || (encoding == UTF_16BE && src.starts_with(b"\xFE\xFF")) >+ { > &src[2..] > } else { > return decode_to_nscstring_without_bom_handling(encoding, src, dst); > }; > decode_from_slice_to_nscstring_without_bom_handling(encoding, without_bom, dst, 0) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_without_bom_handling(encoding: *const Encoding, src: *const nsACString, dst: *mut nsACString) -> nsresult{ >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_without_bom_handling( >+ encoding: *const Encoding, >+ src: *const nsACString, >+ dst: *mut nsACString, >+) -> nsresult { > debug_assert_ne!(src as usize, dst as usize); > decode_to_nscstring_without_bom_handling(&*encoding, &*src, &mut *dst) > } > >-pub fn decode_to_nscstring_without_bom_handling(encoding: &'static Encoding, >- src: &nsACString, >- dst: &mut nsACString) >- -> nsresult { >+pub fn decode_to_nscstring_without_bom_handling( >+ encoding: &'static Encoding, >+ src: &nsACString, >+ dst: &mut nsACString, >+) -> nsresult { > let bytes = &src[..]; > let valid_up_to = if encoding == UTF_8 { > Encoding::utf8_valid_up_to(bytes) > } else if encoding.is_ascii_compatible() { > Encoding::ascii_valid_up_to(bytes) > } else if encoding == ISO_2022_JP { > Encoding::iso_2022_jp_ascii_valid_up_to(bytes) > } else { >@@ -309,49 +361,67 @@ pub fn decode_to_nscstring_without_bom_handling(encoding: &'static Encoding, > return NS_ERROR_OUT_OF_MEMORY; > } > return NS_OK; > } > decode_from_slice_to_nscstring_without_bom_handling(encoding, src, dst, valid_up_to) > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_from_slice_to_nscstring_without_bom_handling(encoding: *const Encoding, src: *const u8, src_len: usize, dst: *mut nsACString, already_validated: usize) -> nsresult { >- decode_from_slice_to_nscstring_without_bom_handling(&*encoding, slice::from_raw_parts(src, src_len), &mut *dst, already_validated) >+pub unsafe extern "C" fn mozilla_encoding_decode_from_slice_to_nscstring_without_bom_handling( >+ encoding: *const Encoding, >+ src: *const u8, >+ src_len: usize, >+ dst: *mut nsACString, >+ already_validated: usize, >+) -> nsresult { >+ decode_from_slice_to_nscstring_without_bom_handling( >+ &*encoding, >+ slice::from_raw_parts(src, src_len), >+ &mut *dst, >+ already_validated, >+ ) > } > >-fn decode_from_slice_to_nscstring_without_bom_handling(encoding: &'static Encoding, >- src: &[u8], >- dst: &mut nsACString, >- already_validated: usize) >- -> nsresult { >+fn decode_from_slice_to_nscstring_without_bom_handling( >+ encoding: &'static Encoding, >+ src: &[u8], >+ dst: &mut nsACString, >+ already_validated: usize, >+) -> nsresult { > let bytes = src; > let mut decoder = encoding.new_decoder_without_bom_handling(); >- let rounded_without_replacement = >- checked_next_power_of_two(checked_add(already_validated, decoder.max_utf8_buffer_length_without_replacement(bytes.len() - already_validated))); >- let with_replacement = checked_add(already_validated, >- decoder.max_utf8_buffer_length(bytes.len() - >- already_validated)); >- try_dst_set_len!(checked_min(rounded_without_replacement, with_replacement), >- dst, >- NS_ERROR_OUT_OF_MEMORY); >+ let rounded_without_replacement = checked_next_power_of_two(checked_add( >+ already_validated, >+ decoder.max_utf8_buffer_length_without_replacement(bytes.len() - already_validated), >+ )); >+ let with_replacement = checked_add( >+ already_validated, >+ decoder.max_utf8_buffer_length(bytes.len() - already_validated), >+ ); >+ try_dst_set_len!( >+ checked_min(rounded_without_replacement, with_replacement), >+ dst, >+ NS_ERROR_OUT_OF_MEMORY >+ ); > > if already_validated != 0 { > // to_mut() shouldn't fail right after setting length. > &mut (dst.to_mut())[..already_validated].copy_from_slice(&bytes[..already_validated]); > } > let mut total_read = already_validated; > let mut total_written = already_validated; > let mut total_had_errors = false; > loop { > // to_mut() shouldn't fail right after setting length. >- let (result, read, written, had_errors) = >- decoder.decode_to_utf8(&bytes[total_read..], >- &mut (dst.to_mut())[total_written..], >- true); >+ let (result, read, written, had_errors) = decoder.decode_to_utf8( >+ &bytes[total_read..], >+ &mut (dst.to_mut())[total_written..], >+ true, >+ ); > total_read += read; > total_written += written; > total_had_errors |= had_errors; > match result { > CoderResult::InputEmpty => { > debug_assert_eq!(total_read, bytes.len()); > unsafe { > if dst.fallible_set_length(total_written as u32).is_err() { >@@ -361,37 +431,44 @@ fn decode_from_slice_to_nscstring_without_bom_handling(encoding: &'static Encodi > if total_had_errors { > return NS_OK_HAD_REPLACEMENTS; > } > return NS_OK; > } > CoderResult::OutputFull => { > // Allocate for the worst case. That is, we should come > // here at most once per invocation of this method. >- try_dst_set_len!(checked_add(total_written, >- decoder.max_utf8_buffer_length(bytes.len() - >- total_read)), >- dst, >- NS_ERROR_OUT_OF_MEMORY); >+ try_dst_set_len!( >+ checked_add( >+ total_written, >+ decoder.max_utf8_buffer_length(bytes.len() - total_read) >+ ), >+ dst, >+ NS_ERROR_OUT_OF_MEMORY >+ ); > continue; > } > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_without_bom_handling_and_without_replacement >- (encoding: *const Encoding, >- src: *const nsACString, >- dst: *mut nsACString) >- -> nsresult { >+pub unsafe extern "C" fn mozilla_encoding_decode_to_nscstring_without_bom_handling_and_without_replacement( >+ encoding: *const Encoding, >+ src: *const nsACString, >+ dst: *mut nsACString, >+) -> nsresult { > decode_to_nscstring_without_bom_handling_and_without_replacement(&*encoding, &*src, &mut *dst) > } > >-pub fn decode_to_nscstring_without_bom_handling_and_without_replacement(encoding: &'static Encoding, src: &nsACString, dst: &mut nsACString) -> nsresult{ >+pub fn decode_to_nscstring_without_bom_handling_and_without_replacement( >+ encoding: &'static Encoding, >+ src: &nsACString, >+ dst: &mut nsACString, >+) -> nsresult { > let bytes = &src[..]; > if encoding == UTF_8 { > let valid_up_to = Encoding::utf8_valid_up_to(bytes); > if valid_up_to == bytes.len() { > if dst.fallible_assign(src).is_err() { > return NS_ERROR_OUT_OF_MEMORY; > } > return NS_OK; >@@ -407,62 +484,72 @@ pub fn decode_to_nscstring_without_bom_handling_and_without_replacement(encoding > }; > if valid_up_to == bytes.len() { > if dst.fallible_assign(src).is_err() { > return NS_ERROR_OUT_OF_MEMORY; > } > return NS_OK; > } > let mut decoder = encoding.new_decoder_without_bom_handling(); >- try_dst_set_len!(checked_add(valid_up_to, >- decoder.max_utf8_buffer_length_without_replacement(bytes.len() - >- valid_up_to)), >- dst, >- NS_ERROR_OUT_OF_MEMORY); >+ try_dst_set_len!( >+ checked_add( >+ valid_up_to, >+ decoder.max_utf8_buffer_length_without_replacement(bytes.len() - valid_up_to) >+ ), >+ dst, >+ NS_ERROR_OUT_OF_MEMORY >+ ); > // to_mut() shouldn't fail right after setting length. > let (result, read, written) = { > let dest = dst.to_mut(); > dest[..valid_up_to].copy_from_slice(&bytes[..valid_up_to]); >- decoder >- .decode_to_utf8_without_replacement(&src[valid_up_to..], &mut dest[valid_up_to..], true) >+ decoder.decode_to_utf8_without_replacement( >+ &src[valid_up_to..], >+ &mut dest[valid_up_to..], >+ true, >+ ) > }; > match result { > DecoderResult::InputEmpty => { > debug_assert_eq!(valid_up_to + read, src.len()); > debug_assert!(valid_up_to + written <= dst.len()); > unsafe { >- if dst.fallible_set_length((valid_up_to + written) as u32) >- .is_err() { >+ if dst >+ .fallible_set_length((valid_up_to + written) as u32) >+ .is_err() >+ { > return NS_ERROR_OUT_OF_MEMORY; > } > } > NS_OK > } > DecoderResult::Malformed(_, _) => { > dst.truncate(); > NS_ERROR_UDEC_ILLEGALINPUT > } > DecoderResult::OutputFull => unreachable!(), > } > } > > #[no_mangle] >-pub unsafe extern "C" fn mozilla_encoding_encode_from_nscstring(encoding: *mut *const Encoding, >- src: *const nsACString, >- dst: *mut nsACString) >- -> nsresult { >+pub unsafe extern "C" fn mozilla_encoding_encode_from_nscstring( >+ encoding: *mut *const Encoding, >+ src: *const nsACString, >+ dst: *mut nsACString, >+) -> nsresult { > let (rv, enc) = encode_from_nscstring(&**encoding, &*src, &mut *dst); > *encoding = enc as *const Encoding; > rv > } > >-pub fn encode_from_nscstring(encoding: &'static Encoding, >- src: &nsACString, >- dst: &mut nsACString) >- -> (nsresult, &'static Encoding) { >+pub fn encode_from_nscstring( >+ encoding: &'static Encoding, >+ src: &nsACString, >+ dst: &mut nsACString, >+) -> (nsresult, &'static Encoding) { > let output_encoding = encoding.output_encoding(); > let bytes = &src[..]; > if output_encoding == UTF_8 { > let valid_up_to = Encoding::utf8_valid_up_to(bytes); > if valid_up_to == bytes.len() { > if dst.fallible_assign(src).is_err() { > return (NS_ERROR_OUT_OF_MEMORY, output_encoding); > } >@@ -487,35 +574,42 @@ pub fn encode_from_nscstring(encoding: &'static Encoding, > // to avoid unsafe blocks. > let trail = if let Ok(trail) = ::std::str::from_utf8(&bytes[valid_up_to..]) { > trail > } else { > return (NS_ERROR_UDEC_ILLEGALINPUT, output_encoding); > }; > > let mut encoder = output_encoding.new_encoder(); >- try_dst_set_len!(checked_add(valid_up_to, >- encoder.max_buffer_length_from_utf8_if_no_unmappables(trail.len())), dst, (NS_ERROR_OUT_OF_MEMORY, output_encoding)); >+ try_dst_set_len!( >+ checked_add( >+ valid_up_to, >+ encoder.max_buffer_length_from_utf8_if_no_unmappables(trail.len()) >+ ), >+ dst, >+ (NS_ERROR_OUT_OF_MEMORY, output_encoding) >+ ); > > if valid_up_to != 0 { > // to_mut() shouldn't fail right after setting length. > &mut (dst.to_mut())[..valid_up_to].copy_from_slice(&bytes[..valid_up_to]); > } > > // `total_read` tracks `trail` only but `total_written` tracks the overall situation! > // This asymmetry is here, because trail is materialized as `str` without resorting > // to unsafe code here. > let mut total_read = 0; > let mut total_written = valid_up_to; > let mut total_had_errors = false; > loop { >- let (result, read, written, had_errors) = encoder >- .encode_from_utf8(&trail[total_read..], >- &mut (dst.to_mut())[total_written..], >- true); >+ let (result, read, written, had_errors) = encoder.encode_from_utf8( >+ &trail[total_read..], >+ &mut (dst.to_mut())[total_written..], >+ true, >+ ); > total_read += read; > total_written += written; > total_had_errors |= had_errors; > match result { > CoderResult::InputEmpty => { > debug_assert_eq!(valid_up_to + total_read, src.len()); > debug_assert!(total_written <= dst.len()); > unsafe { >@@ -524,21 +618,20 @@ pub fn encode_from_nscstring(encoding: &'static Encoding, > } > } > if total_had_errors { > return (NS_OK_HAD_REPLACEMENTS, output_encoding); > } > return (NS_OK, output_encoding); > } > CoderResult::OutputFull => { >- if let Some(needed) = >- checked_add(total_written, >- encoder >- .max_buffer_length_from_utf8_if_no_unmappables(trail.len() - >- total_read)) { >+ if let Some(needed) = checked_add( >+ total_written, >+ encoder.max_buffer_length_from_utf8_if_no_unmappables(trail.len() - total_read), >+ ) { > // Let's round the allocation up in order to avoid repeated > // allocations. Using power-of-two as the approximation of > // available jemalloc buckets, since linking with > // malloc_good_size is messy. > if let Some(with_bookkeeping) = NS_CSTRING_OVERHEAD.checked_add(needed) { > let rounded = with_bookkeeping.next_power_of_two(); > let unclowned = rounded - NS_CSTRING_OVERHEAD; > // XPCOM strings use uint32_t for length. >diff --git a/js/rust/build.rs b/js/rust/build.rs >index 29e21dbfddef..631b1a57a975 100644 >--- a/js/rust/build.rs >+++ b/js/rust/build.rs >@@ -23,31 +23,31 @@ fn build_jsglue_cpp() { > > println!("cargo:rustc-link-search=native={}/lib", dst.display()); > println!("cargo:rustc-link-lib=static=jsglue"); > println!("cargo:rerun-if-changed=src/jsglue.cpp"); > } > > /// Find the public include directory within our mozjs-sys crate dependency. > fn get_mozjs_include_dir() -> path::PathBuf { >- let out_dir = env::var("OUT_DIR") >- .expect("cargo should invoke us with the OUT_DIR env var set"); >+ let out_dir = env::var("OUT_DIR").expect("cargo should invoke us with the OUT_DIR env var set"); > > let mut target_build_dir = path::PathBuf::from(out_dir); > target_build_dir.push("../../"); > > let mut include_dir_glob = target_build_dir.display().to_string(); > include_dir_glob.push_str("mozjs_sys-*/out/dist/include"); > >- let entries = glob::glob(&include_dir_glob) >- .expect("Should find entries for mozjs-sys include dir"); >+ let entries = >+ glob::glob(&include_dir_glob).expect("Should find entries for mozjs-sys include dir"); > > for entry in entries { > if let Ok(path) = entry { >- return path.canonicalize() >+ return path >+ .canonicalize() > .expect("Should canonicalize include path"); > } > } > > panic!("Should have found either a mozjs_sys in target/debug or in target/release"); > } > > /// Invoke bindgen on the JSAPI headers to produce raw FFI bindings for use from >@@ -73,17 +73,18 @@ fn build_jsapi_bindings() { > .clang_arg("-DJS_DEBUG"); > } > > if cfg!(feature = "bigint") { > builder = builder.clang_arg("-DENABLE_BIGINT"); > } > > let include_dir = get_mozjs_include_dir(); >- let include_dir = include_dir.to_str() >+ let include_dir = include_dir >+ .to_str() > .expect("Path to mozjs include dir should be utf-8"); > builder = builder.clang_arg("-I"); > builder = builder.clang_arg(include_dir); > > for ty in UNSAFE_IMPL_SYNC_TYPES { > builder = builder.raw_line(format!("unsafe impl Sync for {} {{}}", ty)); > } > >@@ -110,26 +111,29 @@ fn build_jsapi_bindings() { > for ty in OPAQUE_TYPES { > builder = builder.opaque_type(ty); > } > > for ty in BLACKLIST_TYPES { > builder = builder.blacklist_type(ty); > } > >- let bindings = builder.generate() >+ let bindings = builder >+ .generate() > .expect("Should generate JSAPI bindings OK"); > > let out = path::PathBuf::from(env::var("OUT_DIR").unwrap()); > > if cfg!(feature = "debugmozjs") { >- bindings.write_to_file(out.join("jsapi_debug.rs")) >+ bindings >+ .write_to_file(out.join("jsapi_debug.rs")) > .expect("Should write bindings to file OK"); > } else { >- bindings.write_to_file(out.join("jsapi.rs")) >+ bindings >+ .write_to_file(out.join("jsapi.rs")) > .expect("Should write bindings to file OK"); > } > > println!("cargo:rerun-if-changed=etc/wrapper.hpp"); > } > > /// JSAPI types for which we should implement `Sync`. > const UNSAFE_IMPL_SYNC_TYPES: &'static [&'static str] = &[ >@@ -137,17 +141,18 @@ const UNSAFE_IMPL_SYNC_TYPES: &'static [&'static str] = &[ > "JSFunctionSpec", > "JSNativeWrapper", > "JSPropertySpec", > "JSTypedMethodJitInfo", > ]; > > /// Flags passed through bindgen directly to Clang. > const EXTRA_CLANG_FLAGS: &'static [&'static str] = &[ >- "-x", "c++", >+ "-x", >+ "c++", > "-std=gnu++14", > "-fno-sized-deallocation", > "-DRUST_BINDGEN", > ]; > > /// Types which we want to generate bindings for (and every other type they > /// transitively use). > const WHITELIST_TYPES: &'static [&'static str] = &[ >@@ -472,17 +477,17 @@ const WHITELIST_FUNCTIONS: &'static [&'static str] = &[ > /// These are types which are too tricky for bindgen to handle, and/or use C++ > /// features that don't have an equivalent in rust, such as partial template > /// specialization. > const OPAQUE_TYPES: &'static [&'static str] = &[ > "JS::ReadOnlyCompileOptions", > "mozilla::BufferList", > "mozilla::UniquePtr.*", > "JS::Rooted<JS::Auto.*Vector.*>", >- "JS::Auto.*Vector" >+ "JS::Auto.*Vector", > ]; > > /// Types for which we should NEVER generate bindings, even if it is used within > /// a type or function signature that we are generating bindings for. > const BLACKLIST_TYPES: &'static [&'static str] = &[ > // We provide our own definition because we need to express trait bounds in > // the definition of the struct to make our Drop implementation correct. > "JS::Heap", >diff --git a/js/rust/src/ac.rs b/js/rust/src/ac.rs >index cfd5e8b82e45..aca790d59a38 100644 >--- a/js/rust/src/ac.rs >+++ b/js/rust/src/ac.rs >@@ -2,55 +2,43 @@ use jsapi::root::*; > #[cfg(feature = "debugmozjs")] > use std::ptr; > > #[derive(Debug)] > pub struct AutoCompartment(JSAutoRealmAllowCCW); > > impl AutoCompartment { > #[cfg(feature = "debugmozjs")] >- pub unsafe fn with_obj(cx: *mut JSContext, >- target: *mut JSObject) >- -> AutoCompartment >- { >+ pub unsafe fn with_obj(cx: *mut JSContext, target: *mut JSObject) -> AutoCompartment { > let mut notifier = mozilla::detail::GuardObjectNotifier { > mStatementDone: ptr::null_mut(), > }; > >- AutoCompartment( >- JSAutoRealmAllowCCW::new( >- cx, >- target, >- &mut notifier as *mut _)) >+ AutoCompartment(JSAutoRealmAllowCCW::new( >+ cx, >+ target, >+ &mut notifier as *mut _, >+ )) > } > > #[cfg(not(feature = "debugmozjs"))] >- pub unsafe fn with_obj(cx: *mut JSContext, >- target: *mut JSObject) >- -> AutoCompartment >- { >+ pub unsafe fn with_obj(cx: *mut JSContext, target: *mut JSObject) -> AutoCompartment { > AutoCompartment(JSAutoRealmAllowCCW::new(cx, target)) > } > > #[cfg(feature = "debugmozjs")] >- pub unsafe fn with_script(cx: *mut JSContext, >- target: *mut JSScript) >- -> AutoCompartment >- { >+ pub unsafe fn with_script(cx: *mut JSContext, target: *mut JSScript) -> AutoCompartment { > let mut notifier = mozilla::detail::GuardObjectNotifier { > mStatementDone: ptr::null_mut(), > }; > >- AutoCompartment( >- JSAutoRealmAllowCCW::new1( >- cx, >- target, >- &mut notifier as *mut _)) >+ AutoCompartment(JSAutoRealmAllowCCW::new1( >+ cx, >+ target, >+ &mut notifier as *mut _, >+ )) > } > > #[cfg(not(feature = "debugmozjs"))] >- pub unsafe fn with_script(cx: *mut JSContext, >- target: *mut JSScript) >- -> AutoCompartment >- { >+ pub unsafe fn with_script(cx: *mut JSContext, target: *mut JSScript) -> AutoCompartment { > AutoCompartment(JSAutoRealmAllowCCW::new1(cx, target)) > } > } >diff --git a/js/rust/src/conversions.rs b/js/rust/src/conversions.rs >index 4405ef0945cb..9b38171c49b3 100644 >--- a/js/rust/src/conversions.rs >+++ b/js/rust/src/conversions.rs >@@ -30,37 +30,37 @@ > #[cfg(feature = "nonzero")] > use core::nonzero::NonZero; > > use error::throw_type_error; > use glue::RUST_JS_NumberValue; > use heap::Heap; > use jsapi::root::*; > use jsval::{BooleanValue, Int32Value, NullValue, UInt32Value, UndefinedValue}; >-use jsval::{ObjectValue, ObjectOrNullValue, StringValue}; >-use rust::{ToBoolean, ToInt32, ToInt64, ToNumber, ToUint16, ToUint32, ToUint64}; >-use rust::{ToString, maybe_wrap_object_or_null_value, maybe_wrap_value}; >+use jsval::{ObjectOrNullValue, ObjectValue, StringValue}; > use libc; > use num_traits::{Bounded, Zero}; >+use rust::{maybe_wrap_object_or_null_value, maybe_wrap_value, ToString}; >+use rust::{ToBoolean, ToInt32, ToInt64, ToNumber, ToUint16, ToUint32, ToUint64}; > use std::borrow::Cow; > use std::rc::Rc; > use std::{ptr, slice}; > > trait As<O>: Copy { > fn cast(self) -> O; > } > > macro_rules! impl_as { >- ($I:ty, $O:ty) => ( >+ ($I:ty, $O:ty) => { > impl As<$O> for $I { > fn cast(self) -> $O { > self as $O > } > } >- ) >+ }; > } > > impl_as!(f64, u8); > impl_as!(f64, u16); > impl_as!(f64, u32); > impl_as!(f64, u64); > impl_as!(f64, i8); > impl_as!(f64, i16); >@@ -100,17 +100,17 @@ pub enum ConversionResult<T> { > /// Conversion failed, without a pending exception. > Failure(Cow<'static, str>), > } > > impl<T> ConversionResult<T> { > /// Map a function over the `Success` value. > pub fn map<F, U>(self, mut f: F) -> ConversionResult<U> > where >- F: FnMut(T) -> U >+ F: FnMut(T) -> U, > { > match self { > ConversionResult::Success(t) => ConversionResult::Success(f(t)), > ConversionResult::Failure(e) => ConversionResult::Failure(e), > } > } > > /// Returns Some(value) if it is `ConversionResult::Success`. >@@ -126,20 +126,21 @@ impl<T> ConversionResult<T> { > pub trait FromJSValConvertible: Sized { > /// Optional configurable behaviour switch; use () for no configuration. > type Config; > /// Convert `val` to type `Self`. > /// Optional configuration of type `T` can be passed as the `option` > /// argument. > /// If it returns `Err(())`, a JSAPI exception is pending. > /// If it returns `Ok(Failure(reason))`, there is no pending JSAPI exception. >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: Self::Config) >- -> Result<ConversionResult<Self>, ()>; >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: Self::Config, >+ ) -> Result<ConversionResult<Self>, ()>; > } > > /// Behavior for converting out-of-range integers. > #[derive(PartialEq, Eq, Clone)] > pub enum ConversionBehavior { > /// Wrap into the integer's range. > Default, > /// Throw an exception. >@@ -149,62 +150,70 @@ pub enum ConversionBehavior { > } > > /// Use `T` with `ConversionBehavior::Default` but without requiring any > /// `Config` associated type. > pub struct Default<T>(pub T); > > impl<T> FromJSValConvertible for Default<T> > where >- T: FromJSValConvertible<Config = ConversionBehavior> >+ T: FromJSValConvertible<Config = ConversionBehavior>, > { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, val: JS::HandleValue, _: ()) >- -> Result<ConversionResult<Self>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _: (), >+ ) -> Result<ConversionResult<Self>, ()> { > T::from_jsval(cx, val, ConversionBehavior::Default).map(|conv| conv.map(Default)) > } > } > > /// Use `T` with `ConversionBehavior::EnforceRange` but without requiring any > /// `Config` associated type. > pub struct EnforceRange<T>(pub T); > > impl<T> FromJSValConvertible for EnforceRange<T> >- where >- T: FromJSValConvertible<Config = ConversionBehavior> >+where >+ T: FromJSValConvertible<Config = ConversionBehavior>, > { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, val: JS::HandleValue, _: ()) >- -> Result<ConversionResult<Self>, ()> { >- T::from_jsval(cx, val, ConversionBehavior::EnforceRange) >- .map(|conv| conv.map(EnforceRange)) >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _: (), >+ ) -> Result<ConversionResult<Self>, ()> { >+ T::from_jsval(cx, val, ConversionBehavior::EnforceRange).map(|conv| conv.map(EnforceRange)) > } > } > > /// Use `T` with `ConversionBehavior::Clamp` but without requiring any `Config` > /// associated type. > pub struct Clamp<T>(pub T); > > impl<T> FromJSValConvertible for Clamp<T> >- where >- T: FromJSValConvertible<Config = ConversionBehavior> >+where >+ T: FromJSValConvertible<Config = ConversionBehavior>, > { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, val: JS::HandleValue, _: ()) >- -> Result<ConversionResult<Self>, ()> { >- T::from_jsval(cx, val, ConversionBehavior::Clamp) >- .map(|conv| conv.map(Clamp)) >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _: (), >+ ) -> Result<ConversionResult<Self>, ()> { >+ T::from_jsval(cx, val, ConversionBehavior::Clamp).map(|conv| conv.map(Clamp)) > } > } > > /// Try to cast the number to a smaller type, but > /// if it doesn't fit, it will return an error. > unsafe fn enforce_range<D>(cx: *mut JSContext, d: f64) -> Result<ConversionResult<D>, ()> >- where D: Bounded + As<f64>, >- f64: As<D> >+where >+ D: Bounded + As<f64>, >+ f64: As<D>, > { > if d.is_infinite() { > throw_type_error(cx, "value out of range in an EnforceRange argument"); > return Err(()); > } > > let rounded = d.round(); > if D::min_value().cast() <= rounded && rounded <= D::max_value().cast() { >@@ -214,18 +223,19 @@ unsafe fn enforce_range<D>(cx: *mut JSContext, d: f64) -> Result<ConversionResul > Err(()) > } > } > > /// Try to cast the number to a smaller type, but if it doesn't fit, > /// round it to the MAX or MIN of the source type before casting it to > /// the destination type. > fn clamp_to<D>(d: f64) -> D >- where D: Bounded + As<f64> + Zero, >- f64: As<D> >+where >+ D: Bounded + As<f64> + Zero, >+ f64: As<D>, > { > if d.is_nan() { > D::zero() > } else if d > D::max_value().cast() { > D::max_value() > } else if d < D::min_value().cast() { > D::min_value() > } else { >@@ -239,44 +249,49 @@ impl ToJSValConvertible for () { > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(UndefinedValue()); > } > } > > impl FromJSValConvertible for JS::HandleValue { > type Config = (); > #[inline] >- unsafe fn from_jsval(cx: *mut JSContext, >- value: JS::HandleValue, >- _option: ()) >- -> Result<ConversionResult<JS::HandleValue>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ value: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<JS::HandleValue>, ()> { > if value.is_object() { > js::AssertSameCompartment(cx, value.to_object()); > } > Ok(ConversionResult::Success(value)) > } > } > > impl FromJSValConvertible for JS::Value { > type Config = (); >- unsafe fn from_jsval(_cx: *mut JSContext, >- value: JS::HandleValue, >- _option: ()) >- -> Result<ConversionResult<JS::Value>, ()> { >+ unsafe fn from_jsval( >+ _cx: *mut JSContext, >+ value: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<JS::Value>, ()> { > Ok(ConversionResult::Success(value.get())) > } > } > > impl FromJSValConvertible for Heap<JS::Value> { > type Config = (); >- unsafe fn from_jsval(_cx: *mut JSContext, >- value: JS::HandleValue, >- _option: ()) >- -> Result<ConversionResult<Self>, ()> { >- Ok(ConversionResult::Success(Heap::<JS::Value>::new(value.get()))) >+ unsafe fn from_jsval( >+ _cx: *mut JSContext, >+ value: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<Self>, ()> { >+ Ok(ConversionResult::Success(Heap::<JS::Value>::new( >+ value.get(), >+ ))) > } > } > > impl ToJSValConvertible for JS::Value { > #[inline] > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(*self); > maybe_wrap_value(cx, rval); >@@ -295,228 +310,255 @@ impl ToJSValConvertible for Heap<JS::Value> { > #[inline] > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(self.get()); > maybe_wrap_value(cx, rval); > } > } > > #[inline] >-unsafe fn convert_int_from_jsval<T, M>(cx: *mut JSContext, value: JS::HandleValue, >- option: ConversionBehavior, >- convert_fn: unsafe fn(*mut JSContext, JS::HandleValue) -> Result<M, ()>) >- -> Result<ConversionResult<T>, ()> >- where T: Bounded + Zero + As<f64>, >- M: Zero + As<T>, >- f64: As<T> >+unsafe fn convert_int_from_jsval<T, M>( >+ cx: *mut JSContext, >+ value: JS::HandleValue, >+ option: ConversionBehavior, >+ convert_fn: unsafe fn(*mut JSContext, JS::HandleValue) -> Result<M, ()>, >+) -> Result<ConversionResult<T>, ()> >+where >+ T: Bounded + Zero + As<f64>, >+ M: Zero + As<T>, >+ f64: As<T>, > { > match option { >- ConversionBehavior::Default => Ok(ConversionResult::Success(try!(convert_fn(cx, value)).cast())), >+ ConversionBehavior::Default => Ok(ConversionResult::Success( >+ try!(convert_fn(cx, value)).cast(), >+ )), > ConversionBehavior::EnforceRange => enforce_range(cx, try!(ToNumber(cx, value))), >- ConversionBehavior::Clamp => Ok(ConversionResult::Success(clamp_to(try!(ToNumber(cx, value))))), >+ ConversionBehavior::Clamp => Ok(ConversionResult::Success(clamp_to(try!(ToNumber( >+ cx, value >+ ))))), > } > } > > // https://heycam.github.io/webidl/#es-boolean > impl ToJSValConvertible for bool { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(BooleanValue(*self)); > } > } > > // https://heycam.github.io/webidl/#es-boolean > impl FromJSValConvertible for bool { > type Config = (); >- unsafe fn from_jsval(_cx: *mut JSContext, val: JS::HandleValue, _option: ()) -> Result<ConversionResult<bool>, ()> { >+ unsafe fn from_jsval( >+ _cx: *mut JSContext, >+ val: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<bool>, ()> { > Ok(ToBoolean(val)).map(ConversionResult::Success) > } > } > > // https://heycam.github.io/webidl/#es-byte > impl ToJSValConvertible for i8 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(Int32Value(*self as i32)); > } > } > > // https://heycam.github.io/webidl/#es-byte > impl FromJSValConvertible for i8 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<i8>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<i8>, ()> { > convert_int_from_jsval(cx, val, option, ToInt32) > } > } > > // https://heycam.github.io/webidl/#es-octet > impl ToJSValConvertible for u8 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(Int32Value(*self as i32)); > } > } > > // https://heycam.github.io/webidl/#es-octet > impl FromJSValConvertible for u8 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<u8>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<u8>, ()> { > convert_int_from_jsval(cx, val, option, ToInt32) > } > } > > // https://heycam.github.io/webidl/#es-short > impl ToJSValConvertible for i16 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(Int32Value(*self as i32)); > } > } > > // https://heycam.github.io/webidl/#es-short > impl FromJSValConvertible for i16 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<i16>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<i16>, ()> { > convert_int_from_jsval(cx, val, option, ToInt32) > } > } > > // https://heycam.github.io/webidl/#es-unsigned-short > impl ToJSValConvertible for u16 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(Int32Value(*self as i32)); > } > } > > // https://heycam.github.io/webidl/#es-unsigned-short > impl FromJSValConvertible for u16 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<u16>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<u16>, ()> { > convert_int_from_jsval(cx, val, option, ToUint16) > } > } > > // https://heycam.github.io/webidl/#es-long > impl ToJSValConvertible for i32 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(Int32Value(*self)); > } > } > > // https://heycam.github.io/webidl/#es-long > impl FromJSValConvertible for i32 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<i32>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<i32>, ()> { > convert_int_from_jsval(cx, val, option, ToInt32) > } > } > > // https://heycam.github.io/webidl/#es-unsigned-long > impl ToJSValConvertible for u32 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(UInt32Value(*self)); > } > } > > // https://heycam.github.io/webidl/#es-unsigned-long > impl FromJSValConvertible for u32 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<u32>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<u32>, ()> { > convert_int_from_jsval(cx, val, option, ToUint32) > } > } > > // https://heycam.github.io/webidl/#es-long-long > impl ToJSValConvertible for i64 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(RUST_JS_NumberValue(*self as f64)); > } > } > > // https://heycam.github.io/webidl/#es-long-long > impl FromJSValConvertible for i64 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<i64>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<i64>, ()> { > convert_int_from_jsval(cx, val, option, ToInt64) > } > } > > // https://heycam.github.io/webidl/#es-unsigned-long-long > impl ToJSValConvertible for u64 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(RUST_JS_NumberValue(*self as f64)); > } > } > > // https://heycam.github.io/webidl/#es-unsigned-long-long > impl FromJSValConvertible for u64 { > type Config = ConversionBehavior; >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- option: ConversionBehavior) >- -> Result<ConversionResult<u64>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ option: ConversionBehavior, >+ ) -> Result<ConversionResult<u64>, ()> { > convert_int_from_jsval(cx, val, option, ToUint64) > } > } > > // https://heycam.github.io/webidl/#es-float > impl ToJSValConvertible for f32 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(RUST_JS_NumberValue(*self as f64)); > } > } > > // https://heycam.github.io/webidl/#es-float > impl FromJSValConvertible for f32 { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, val: JS::HandleValue, _option: ()) -> Result<ConversionResult<f32>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<f32>, ()> { > let result = ToNumber(cx, val); > result.map(|f| f as f32).map(ConversionResult::Success) > } > } > > // https://heycam.github.io/webidl/#es-double > impl ToJSValConvertible for f64 { > #[inline] > unsafe fn to_jsval(&self, _cx: *mut JSContext, rval: JS::MutableHandleValue) { > rval.set(RUST_JS_NumberValue(*self)); > } > } > > // https://heycam.github.io/webidl/#es-double > impl FromJSValConvertible for f64 { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, val: JS::HandleValue, _option: ()) -> Result<ConversionResult<f64>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _option: (), >+ ) -> Result<ConversionResult<f64>, ()> { > ToNumber(cx, val).map(ConversionResult::Success) > } > } > > /// Converts a `JSString`, encoded in "Latin1" (i.e. U+0000-U+00FF encoded as 0x00-0xFF) into a > /// `String`. > pub unsafe fn latin1_to_string(cx: *mut JSContext, s: *mut JSString) -> String { > assert!(JS_StringHasLatin1Chars(s)); >@@ -532,19 +574,21 @@ pub unsafe fn latin1_to_string(cx: *mut JSContext, s: *mut JSString) -> String { > } > > // https://heycam.github.io/webidl/#es-USVString > impl ToJSValConvertible for str { > #[inline] > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { > let mut string_utf16: Vec<u16> = Vec::with_capacity(self.len()); > string_utf16.extend(self.encode_utf16()); >- let jsstr = JS_NewUCStringCopyN(cx, >- string_utf16.as_ptr(), >- string_utf16.len() as libc::size_t); >+ let jsstr = JS_NewUCStringCopyN( >+ cx, >+ string_utf16.as_ptr(), >+ string_utf16.len() as libc::size_t, >+ ); > if jsstr.is_null() { > panic!("JS_NewUCStringCopyN failed"); > } > rval.set(StringValue(&*jsstr)); > } > } > > // https://heycam.github.io/webidl/#es-USVString >@@ -553,17 +597,21 @@ impl ToJSValConvertible for String { > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { > (**self).to_jsval(cx, rval); > } > } > > // https://heycam.github.io/webidl/#es-USVString > impl FromJSValConvertible for String { > type Config = (); >- unsafe fn from_jsval(cx: *mut JSContext, value: JS::HandleValue, _: ()) -> Result<ConversionResult<String>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ value: JS::HandleValue, >+ _: (), >+ ) -> Result<ConversionResult<String>, ()> { > let jsstr = ToString(cx, value); > if jsstr.is_null() { > debug!("ToString failed"); > return Err(()); > } > if JS_StringHasLatin1Chars(jsstr) { > return Ok(latin1_to_string(cx, jsstr)).map(ConversionResult::Success); > } >@@ -590,27 +638,30 @@ impl<T: ToJSValConvertible> ToJSValConvertible for Rc<T> { > #[inline] > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { > (**self).to_jsval(cx, rval) > } > } > > impl<T: FromJSValConvertible> FromJSValConvertible for Option<T> { > type Config = T::Config; >- unsafe fn from_jsval(cx: *mut JSContext, >- value: JS::HandleValue, >- option: T::Config) >- -> Result<ConversionResult<Option<T>>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ value: JS::HandleValue, >+ option: T::Config, >+ ) -> Result<ConversionResult<Option<T>>, ()> { > if value.get().is_null_or_undefined() { > Ok(ConversionResult::Success(None)) > } else { >- Ok(match try!(FromJSValConvertible::from_jsval(cx, value, option)) { >- ConversionResult::Success(v) => ConversionResult::Success(Some(v)), >- ConversionResult::Failure(v) => ConversionResult::Failure(v), >- }) >+ Ok( >+ match try!(FromJSValConvertible::from_jsval(cx, value, option)) { >+ ConversionResult::Success(v) => ConversionResult::Success(Some(v)), >+ ConversionResult::Failure(v) => ConversionResult::Failure(v), >+ }, >+ ) > } > } > } > > // https://heycam.github.io/webidl/#es-sequence > impl<T: ToJSValConvertible> ToJSValConvertible for Vec<T> { > #[inline] > unsafe fn to_jsval(&self, cx: *mut JSContext, rval: JS::MutableHandleValue) { >@@ -634,81 +685,85 @@ impl<T: ToJSValConvertible> ToJSValConvertible for Vec<T> { > } > } > > /// Rooting guard for the iterator and nextMethod fields of ForOfIterator. > /// Behaves like RootedGuard (roots on creation, unroots on drop), > /// but borrows and allows access to the whole ForOfIterator, so > /// that methods on ForOfIterator can still be used through it. > struct ForOfIteratorGuard<'a> { >- root: &'a mut JS::ForOfIterator >+ root: &'a mut JS::ForOfIterator, > } > > impl<'a> ForOfIteratorGuard<'a> { > fn new(cx: *mut JSContext, root: &'a mut JS::ForOfIterator) -> Self { > unsafe { > root.iterator.register_with_root_lists(cx); > root.nextMethod.register_with_root_lists(cx); > } >- ForOfIteratorGuard { >- root: root >- } >+ ForOfIteratorGuard { root: root } > } > } > > impl<'a> Drop for ForOfIteratorGuard<'a> { > fn drop(&mut self) { > unsafe { > self.root.nextMethod.remove_from_root_stack(); > self.root.iterator.remove_from_root_stack(); > } > } > } > >-impl<C: Clone, T: FromJSValConvertible<Config=C>> FromJSValConvertible for Vec<T> { >+impl<C: Clone, T: FromJSValConvertible<Config = C>> FromJSValConvertible for Vec<T> { > type Config = C; > >- unsafe fn from_jsval(cx: *mut JSContext, >- value: JS::HandleValue, >- option: C) >- -> Result<ConversionResult<Vec<T>>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ value: JS::HandleValue, >+ option: C, >+ ) -> Result<ConversionResult<Vec<T>>, ()> { > let mut iterator = JS::ForOfIterator { > cx_: cx, > iterator: JS::RootedObject::new_unrooted(), > nextMethod: JS::RootedValue::new_unrooted(), > index: ::std::u32::MAX, // NOT_ARRAY > }; > let iterator = ForOfIteratorGuard::new(cx, &mut iterator); > let iterator = &mut *iterator.root; > >- if !iterator.init(value, JS::ForOfIterator_NonIterableBehavior::AllowNonIterable) { >- return Err(()) >+ if !iterator.init( >+ value, >+ JS::ForOfIterator_NonIterableBehavior::AllowNonIterable, >+ ) { >+ return Err(()); > } > > if iterator.iterator.ptr.is_null() { > return Ok(ConversionResult::Failure("Value is not iterable".into())); > } > > let mut ret = vec![]; > > loop { > let mut done = false; > rooted!(in(cx) let mut val = UndefinedValue()); > if !iterator.next(val.handle_mut(), &mut done) { >- return Err(()) >+ return Err(()); > } > > if done { > break; > } > >- ret.push(match try!(T::from_jsval(cx, val.handle(), option.clone())) { >- ConversionResult::Success(v) => v, >- ConversionResult::Failure(e) => return Ok(ConversionResult::Failure(e)), >- }); >+ ret.push( >+ match try!(T::from_jsval(cx, val.handle(), option.clone())) { >+ ConversionResult::Success(v) => v, >+ ConversionResult::Failure(e) => return Ok(ConversionResult::Failure(e)), >+ }, >+ ); > } > > Ok(ret).map(ConversionResult::Success) > } > } > > // https://heycam.github.io/webidl/#es-object > impl ToJSValConvertible for *mut JSObject { >@@ -773,20 +828,21 @@ impl ToJSValConvertible for JS::Handle<*mut JSFunction> { > rval.set(ObjectOrNullValue(self.get() as *mut JSObject)); > maybe_wrap_object_or_null_value(cx, rval); > } > } > > impl FromJSValConvertible for *mut JSFunction { > type Config = (); > >- unsafe fn from_jsval(cx: *mut JSContext, >- val: JS::HandleValue, >- _: ()) >- -> Result<ConversionResult<Self>, ()> { >+ unsafe fn from_jsval( >+ cx: *mut JSContext, >+ val: JS::HandleValue, >+ _: (), >+ ) -> Result<ConversionResult<Self>, ()> { > let func = JS_ValueToFunction(cx, val); > if func.is_null() { > Ok(ConversionResult::Failure("value is not a function".into())) > } else { > Ok(ConversionResult::Success(func)) > } > } > } >diff --git a/js/rust/src/error.rs b/js/rust/src/error.rs >index 1216e8b02b32..34a5fa828ab6 100644 >--- a/js/rust/src/error.rs >+++ b/js/rust/src/error.rs >@@ -32,39 +32,44 @@ static mut RANGE_ERROR_FORMAT_STRING: JSErrorFormatString = JSErrorFormatString > name: b"RUSTMSG_RANGE_ERROR\0" as *const _ as *const libc::c_char, > format: &ERROR_FORMAT_STRING_STRING as *const libc::c_char, > argCount: 1, > exnType: JSExnType::JSEXN_RANGEERR as i16, > }; > > /// Callback used to throw javascript errors. > /// See throw_js_error for info about error_number. >-unsafe extern "C" fn get_error_message(_user_ref: *mut os::raw::c_void, >- error_number: libc::c_uint) >- -> *const JSErrorFormatString { >+unsafe extern "C" fn get_error_message( >+ _user_ref: *mut os::raw::c_void, >+ error_number: libc::c_uint, >+) -> *const JSErrorFormatString { > let num: JSExnType = mem::transmute(error_number); > match num { > JSExnType::JSEXN_TYPEERR => &TYPE_ERROR_FORMAT_STRING as *const JSErrorFormatString, > JSExnType::JSEXN_RANGEERR => &RANGE_ERROR_FORMAT_STRING as *const JSErrorFormatString, >- _ => panic!("Bad js error number given to get_error_message: {}", >- error_number), >+ _ => panic!( >+ "Bad js error number given to get_error_message: {}", >+ error_number >+ ), > } > } > > /// Helper fn to throw a javascript error with the given message and number. > /// Reuse the jsapi error codes to distinguish the error_number > /// passed back to the get_error_message callback. > /// c_uint is u32, so this cast is safe, as is casting to/from i32 from there. > unsafe fn throw_js_error(cx: *mut JSContext, error: &str, error_number: u32) { > let error = CString::new(error).unwrap(); >- JS_ReportErrorNumberUTF8(cx, >- Some(get_error_message), >- ptr::null_mut(), >- error_number, >- error.as_ptr()); >+ JS_ReportErrorNumberUTF8( >+ cx, >+ Some(get_error_message), >+ ptr::null_mut(), >+ error_number, >+ error.as_ptr(), >+ ); > } > > /// Throw a `TypeError` with the given message. > pub unsafe fn throw_type_error(cx: *mut JSContext, error: &str) { > throw_js_error(cx, error, JSExnType::JSEXN_TYPEERR as u32); > } > > /// Throw a `RangeError` with the given message. >diff --git a/js/rust/src/glue.rs b/js/rust/src/glue.rs >index 362c08d69cb0..5d46730865e8 100644 >--- a/js/rust/src/glue.rs >+++ b/js/rust/src/glue.rs >@@ -1,145 +1,198 @@ >-use jsapi::root::*; > use heap::Heap; >+use jsapi::root::*; > use std::os::raw::c_void; > >- >-pub enum Action { } >+pub enum Action {} > unsafe impl Sync for ProxyTraps {} > > #[repr(C)] > #[derive(Copy, Clone)] > pub struct ProxyTraps { >- pub enter: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- action: Action, >- bp: *mut bool) >- -> bool>, >- pub getOwnPropertyDescriptor: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- desc: JS::MutableHandle<JS::PropertyDescriptor>) >- -> bool>, >- pub defineProperty: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- desc: JS::Handle<JS::PropertyDescriptor>, >- result: *mut JS::ObjectOpResult) >- -> bool>, >- pub ownPropertyKeys: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- props: *mut JS::AutoIdVector) >- -> bool>, >- pub delete_: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- result: *mut JS::ObjectOpResult) >- -> bool>, >- pub enumerate: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- objp: JS::MutableHandleObject) >- -> bool>, >- pub getPrototypeIfOrdinary: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- isOrdinary: *mut bool, >- protop: JS::MutableHandleObject) >- -> bool>, >- pub preventExtensions: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- result: *mut JS::ObjectOpResult) >- -> bool>, >- pub isExtensible: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- succeeded: *mut bool) >- -> bool>, >- pub has: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- bp: *mut bool) >- -> bool>, >- pub get: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- receiver: JS::HandleValue, >- id: JS::HandleId, >- vp: JS::MutableHandleValue) >- -> bool>, >- pub set: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- v: JS::HandleValue, >- receiver: JS::HandleValue, >- result: *mut JS::ObjectOpResult) >- -> bool>, >- pub call: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- args: *const JS::CallArgs) >- -> bool>, >- pub construct: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- args: *const JS::CallArgs) >- -> bool>, >- pub getPropertyDescriptor: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- desc: JS::MutableHandle<JS::PropertyDescriptor>) >- -> bool>, >- pub hasOwn: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- bp: *mut bool) >- -> bool>, >- pub getOwnEnumerablePropertyKeys: >- ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- props: *mut JS::AutoIdVector) >- -> bool>, >- pub nativeCall: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- test: JS::IsAcceptableThis, >- _impl: JS::NativeImpl, >- args: JS::CallArgs) >- -> bool>, >- pub hasInstance: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- v: JS::MutableHandleValue, >- bp: *mut bool) >- -> bool>, >- pub objectClassIs: ::std::option::Option<unsafe extern "C" fn(obj: JS::HandleObject, >- classValue: js::ESClass, >- cx: *mut JSContext) >- -> bool>, >- pub className: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject) >- -> *const i8>, >- pub fun_toString: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- indent: u32) >- -> *mut JSString>, >- pub boxedValue_unbox: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- proxy: JS::HandleObject, >- vp: JS::MutableHandleValue) >- -> bool>, >- pub defaultValue: ::std::option::Option<unsafe extern "C" fn(cx: *mut JSContext, >- obj: JS::HandleObject, >- hint: JSType, >- vp: JS::MutableHandleValue) >- -> bool>, >+ pub enter: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ action: Action, >+ bp: *mut bool, >+ ) -> bool, >+ >, >+ pub getOwnPropertyDescriptor: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ desc: JS::MutableHandle<JS::PropertyDescriptor>, >+ ) -> bool, >+ >, >+ pub defineProperty: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ desc: JS::Handle<JS::PropertyDescriptor>, >+ result: *mut JS::ObjectOpResult, >+ ) -> bool, >+ >, >+ pub ownPropertyKeys: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ props: *mut JS::AutoIdVector, >+ ) -> bool, >+ >, >+ pub delete_: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ result: *mut JS::ObjectOpResult, >+ ) -> bool, >+ >, >+ pub enumerate: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ objp: JS::MutableHandleObject, >+ ) -> bool, >+ >, >+ pub getPrototypeIfOrdinary: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ isOrdinary: *mut bool, >+ protop: JS::MutableHandleObject, >+ ) -> bool, >+ >, >+ pub preventExtensions: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ result: *mut JS::ObjectOpResult, >+ ) -> bool, >+ >, >+ pub isExtensible: ::std::option::Option< >+ unsafe extern "C" fn(cx: *mut JSContext, proxy: JS::HandleObject, succeeded: *mut bool) >+ -> bool, >+ >, >+ pub has: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ bp: *mut bool, >+ ) -> bool, >+ >, >+ pub get: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ receiver: JS::HandleValue, >+ id: JS::HandleId, >+ vp: JS::MutableHandleValue, >+ ) -> bool, >+ >, >+ pub set: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ v: JS::HandleValue, >+ receiver: JS::HandleValue, >+ result: *mut JS::ObjectOpResult, >+ ) -> bool, >+ >, >+ pub call: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ args: *const JS::CallArgs, >+ ) -> bool, >+ >, >+ pub construct: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ args: *const JS::CallArgs, >+ ) -> bool, >+ >, >+ pub getPropertyDescriptor: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ desc: JS::MutableHandle<JS::PropertyDescriptor>, >+ ) -> bool, >+ >, >+ pub hasOwn: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ bp: *mut bool, >+ ) -> bool, >+ >, >+ pub getOwnEnumerablePropertyKeys: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ props: *mut JS::AutoIdVector, >+ ) -> bool, >+ >, >+ pub nativeCall: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ test: JS::IsAcceptableThis, >+ _impl: JS::NativeImpl, >+ args: JS::CallArgs, >+ ) -> bool, >+ >, >+ pub hasInstance: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ v: JS::MutableHandleValue, >+ bp: *mut bool, >+ ) -> bool, >+ >, >+ pub objectClassIs: ::std::option::Option< >+ unsafe extern "C" fn(obj: JS::HandleObject, classValue: js::ESClass, cx: *mut JSContext) >+ -> bool, >+ >, >+ pub className: ::std::option::Option< >+ unsafe extern "C" fn(cx: *mut JSContext, proxy: JS::HandleObject) -> *const i8, >+ >, >+ pub fun_toString: ::std::option::Option< >+ unsafe extern "C" fn(cx: *mut JSContext, proxy: JS::HandleObject, indent: u32) >+ -> *mut JSString, >+ >, >+ pub boxedValue_unbox: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ vp: JS::MutableHandleValue, >+ ) -> bool, >+ >, >+ pub defaultValue: ::std::option::Option< >+ unsafe extern "C" fn( >+ cx: *mut JSContext, >+ obj: JS::HandleObject, >+ hint: JSType, >+ vp: JS::MutableHandleValue, >+ ) -> bool, >+ >, > pub trace: > ::std::option::Option<unsafe extern "C" fn(trc: *mut JSTracer, proxy: *mut JSObject)>, > pub finalize: > ::std::option::Option<unsafe extern "C" fn(fop: *mut JSFreeOp, proxy: *mut JSObject)>, >- pub objectMoved: >- ::std::option::Option<unsafe extern "C" fn(proxy: *mut JSObject, >- old: *mut JSObject) -> usize>, >+ pub objectMoved: ::std::option::Option< >+ unsafe extern "C" fn(proxy: *mut JSObject, old: *mut JSObject) -> usize, >+ >, > pub isCallable: ::std::option::Option<unsafe extern "C" fn(obj: *mut JSObject) -> bool>, > pub isConstructor: ::std::option::Option<unsafe extern "C" fn(obj: *mut JSObject) -> bool>, > } > impl ::std::default::Default for ProxyTraps { > fn default() -> ProxyTraps { > unsafe { ::std::mem::zeroed() } > } > } >@@ -161,189 +214,231 @@ pub struct ForwardingProxyHandler { > } > impl ::std::default::Default for ForwardingProxyHandler { > fn default() -> ForwardingProxyHandler { > unsafe { ::std::mem::zeroed() } > } > } > > extern "C" { >- pub fn InvokeGetOwnPropertyDescriptor(handler: *const ::libc::c_void, >- cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- desc: JS::MutableHandle<JS::PropertyDescriptor>) >- -> bool; >- pub fn InvokeHasOwn(handler: *const ::libc::c_void, >- cx: *mut JSContext, >- proxy: JS::HandleObject, >- id: JS::HandleId, >- bp: *mut bool) >- -> bool; >+ pub fn InvokeGetOwnPropertyDescriptor( >+ handler: *const ::libc::c_void, >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ desc: JS::MutableHandle<JS::PropertyDescriptor>, >+ ) -> bool; >+ pub fn InvokeHasOwn( >+ handler: *const ::libc::c_void, >+ cx: *mut JSContext, >+ proxy: JS::HandleObject, >+ id: JS::HandleId, >+ bp: *mut bool, >+ ) -> bool; > pub fn RUST_JS_NumberValue(d: f64) -> JS::Value; > pub fn RUST_FUNCTION_VALUE_TO_JITINFO(v: JS::Value) -> *const JSJitInfo; > pub fn CreateCallArgsFromVp(argc: u32, v: *mut JS::Value) -> JS::CallArgs; >- pub fn CallJitGetterOp(info: *const JSJitInfo, >- cx: *mut JSContext, >- thisObj: JS::HandleObject, >- specializedThis: *mut ::libc::c_void, >- argc: u32, >- vp: *mut JS::Value) >- -> bool; >- pub fn CallJitSetterOp(info: *const JSJitInfo, >- cx: *mut JSContext, >- thisObj: JS::HandleObject, >- specializedThis: *mut ::libc::c_void, >- argc: u32, >- vp: *mut JS::Value) >- -> bool; >- pub fn CallJitMethodOp(info: *const JSJitInfo, >- cx: *mut JSContext, >- thisObj: JS::HandleObject, >- specializedThis: *mut ::libc::c_void, >- argc: u32, >- vp: *mut JS::Value) >- -> bool; >- pub fn CreateProxyHandler(aTraps: *const ProxyTraps, >- aExtra: *const ::libc::c_void) >- -> *const ::libc::c_void; >+ pub fn CallJitGetterOp( >+ info: *const JSJitInfo, >+ cx: *mut JSContext, >+ thisObj: JS::HandleObject, >+ specializedThis: *mut ::libc::c_void, >+ argc: u32, >+ vp: *mut JS::Value, >+ ) -> bool; >+ pub fn CallJitSetterOp( >+ info: *const JSJitInfo, >+ cx: *mut JSContext, >+ thisObj: JS::HandleObject, >+ specializedThis: *mut ::libc::c_void, >+ argc: u32, >+ vp: *mut JS::Value, >+ ) -> bool; >+ pub fn CallJitMethodOp( >+ info: *const JSJitInfo, >+ cx: *mut JSContext, >+ thisObj: JS::HandleObject, >+ specializedThis: *mut ::libc::c_void, >+ argc: u32, >+ vp: *mut JS::Value, >+ ) -> bool; >+ pub fn CreateProxyHandler( >+ aTraps: *const ProxyTraps, >+ aExtra: *const ::libc::c_void, >+ ) -> *const ::libc::c_void; > pub fn CreateWrapperProxyHandler(aTraps: *const ProxyTraps) -> *const ::libc::c_void; >- pub fn CreateRustJSPrincipal(origin: *const ::libc::c_void, >- destroy: Option<unsafe extern "C" fn >- (principal: *mut JSPrincipals)>, >- write: Option<unsafe extern "C" fn >- (cx: *mut JSContext, >- writer: *mut JSStructuredCloneWriter) >- -> bool>) >--> *mut JSPrincipals; >+ pub fn CreateRustJSPrincipal( >+ origin: *const ::libc::c_void, >+ destroy: Option<unsafe extern "C" fn(principal: *mut JSPrincipals)>, >+ write: Option< >+ unsafe extern "C" fn(cx: *mut JSContext, writer: *mut JSStructuredCloneWriter) -> bool, >+ >, >+ ) -> *mut JSPrincipals; > pub fn GetPrincipalOrigin(principal: *const JSPrincipals) -> *const ::libc::c_void; > pub fn GetCrossCompartmentWrapper() -> *const ::libc::c_void; > pub fn GetSecurityWrapper() -> *const ::libc::c_void; >- pub fn NewCompileOptions(aCx: *mut JSContext, >- aFile: *const ::libc::c_char, >- aLine: u32) >- -> *mut JS::ReadOnlyCompileOptions; >+ pub fn NewCompileOptions( >+ aCx: *mut JSContext, >+ aFile: *const ::libc::c_char, >+ aLine: u32, >+ ) -> *mut JS::ReadOnlyCompileOptions; > pub fn DeleteCompileOptions(aOpts: *mut JS::ReadOnlyCompileOptions); >- pub fn NewProxyObject(aCx: *mut JSContext, >- aHandler: *const ::libc::c_void, >- aPriv: JS::HandleValue, >- proto: *mut JSObject, >- parent: *mut JSObject, >- call: *mut JSObject, >- construct: *mut JSObject) >- -> *mut JSObject; >- pub fn WrapperNew(aCx: *mut JSContext, >- aObj: JS::HandleObject, >- aHandler: *const ::libc::c_void, >- aClass: *const JSClass, >- aSingleton: bool) >- -> *mut JSObject; >- pub fn NewWindowProxy(aCx: *mut JSContext, >- aObj: JS::HandleObject, >- aHandler: *const ::libc::c_void) >- -> *mut JSObject; >+ pub fn NewProxyObject( >+ aCx: *mut JSContext, >+ aHandler: *const ::libc::c_void, >+ aPriv: JS::HandleValue, >+ proto: *mut JSObject, >+ parent: *mut JSObject, >+ call: *mut JSObject, >+ construct: *mut JSObject, >+ ) -> *mut JSObject; >+ pub fn WrapperNew( >+ aCx: *mut JSContext, >+ aObj: JS::HandleObject, >+ aHandler: *const ::libc::c_void, >+ aClass: *const JSClass, >+ aSingleton: bool, >+ ) -> *mut JSObject; >+ pub fn NewWindowProxy( >+ aCx: *mut JSContext, >+ aObj: JS::HandleObject, >+ aHandler: *const ::libc::c_void, >+ ) -> *mut JSObject; > pub fn GetWindowProxyClass() -> *const js::Class; > pub fn GetProxyPrivate(obj: *mut JSObject) -> JS::Value; > pub fn SetProxyPrivate(obj: *mut JSObject, private: *const JS::Value); > pub fn GetProxyReservedSlot(obj: *mut JSObject, slot: u32) -> JS::Value; > pub fn SetProxyReservedSlot(obj: *mut JSObject, slot: u32, val: *const JS::Value); > pub fn RUST_JSID_IS_INT(id: JS::HandleId) -> bool; > pub fn RUST_JSID_TO_INT(id: JS::HandleId) -> i32; > pub fn int_to_jsid(i: i32) -> jsid; > pub fn RUST_JSID_IS_STRING(id: JS::HandleId) -> bool; > pub fn RUST_JSID_TO_STRING(id: JS::HandleId) -> *mut JSString; > pub fn RUST_SYMBOL_TO_JSID(sym: *mut JS::Symbol) -> jsid; > pub fn RUST_SET_JITINFO(func: *mut JSFunction, info: *const JSJitInfo); > pub fn RUST_INTERNED_STRING_TO_JSID(cx: *mut JSContext, str: *mut JSString) -> jsid; >- pub fn RUST_js_GetErrorMessage(userRef: *mut ::libc::c_void, >- errorNumber: u32) >- -> *const JSErrorFormatString; >+ pub fn RUST_js_GetErrorMessage( >+ userRef: *mut ::libc::c_void, >+ errorNumber: u32, >+ ) -> *const JSErrorFormatString; > pub fn IsProxyHandlerFamily(obj: *mut JSObject) -> u8; > pub fn GetProxyHandlerExtra(obj: *mut JSObject) -> *const ::libc::c_void; > pub fn GetProxyHandler(obj: *mut JSObject) -> *const ::libc::c_void; > pub fn ReportError(aCx: *mut JSContext, aError: *const i8); > pub fn IsWrapper(obj: *mut JSObject) -> bool; > pub fn UnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject; > pub fn UncheckedUnwrapObject(obj: *mut JSObject, stopAtOuter: u8) -> *mut JSObject; > pub fn CreateAutoIdVector(cx: *mut JSContext) -> *mut JS::AutoIdVector; > pub fn AppendToAutoIdVector(v: *mut JS::AutoIdVector, id: jsid) -> bool; > pub fn SliceAutoIdVector(v: *const JS::AutoIdVector, length: *mut usize) -> *const jsid; > pub fn DestroyAutoIdVector(v: *mut JS::AutoIdVector); > pub fn CreateAutoObjectVector(aCx: *mut JSContext) -> *mut JS::AutoObjectVector; > pub fn AppendToAutoObjectVector(v: *mut JS::AutoObjectVector, obj: *mut JSObject) -> bool; > pub fn DeleteAutoObjectVector(v: *mut JS::AutoObjectVector); > pub fn CollectServoSizes(rt: *mut JSRuntime, sizes: *mut JS::ServoSizes) -> bool; > pub fn CallIdTracer(trc: *mut JSTracer, idp: *mut Heap<jsid>, name: *const ::libc::c_char); >- pub fn CallValueTracer(trc: *mut JSTracer, >- valuep: *mut Heap<JS::Value>, >- name: *const ::libc::c_char); >- pub fn CallObjectTracer(trc: *mut JSTracer, >- objp: *mut Heap<*mut JSObject>, >- name: *const ::libc::c_char); >- pub fn CallStringTracer(trc: *mut JSTracer, >- strp: *mut Heap<*mut JSString>, >- name: *const ::libc::c_char); >- pub fn CallScriptTracer(trc: *mut JSTracer, >- scriptp: *mut Heap<*mut JSScript>, >- name: *const ::libc::c_char); >- pub fn CallFunctionTracer(trc: *mut JSTracer, >- funp: *mut Heap<*mut JSFunction>, >- name: *const ::libc::c_char); >- pub fn CallUnbarrieredObjectTracer(trc: *mut JSTracer, >- objp: *mut *mut JSObject, >- name: *const ::libc::c_char); >+ pub fn CallValueTracer( >+ trc: *mut JSTracer, >+ valuep: *mut Heap<JS::Value>, >+ name: *const ::libc::c_char, >+ ); >+ pub fn CallObjectTracer( >+ trc: *mut JSTracer, >+ objp: *mut Heap<*mut JSObject>, >+ name: *const ::libc::c_char, >+ ); >+ pub fn CallStringTracer( >+ trc: *mut JSTracer, >+ strp: *mut Heap<*mut JSString>, >+ name: *const ::libc::c_char, >+ ); >+ pub fn CallScriptTracer( >+ trc: *mut JSTracer, >+ scriptp: *mut Heap<*mut JSScript>, >+ name: *const ::libc::c_char, >+ ); >+ pub fn CallFunctionTracer( >+ trc: *mut JSTracer, >+ funp: *mut Heap<*mut JSFunction>, >+ name: *const ::libc::c_char, >+ ); >+ pub fn CallUnbarrieredObjectTracer( >+ trc: *mut JSTracer, >+ objp: *mut *mut JSObject, >+ name: *const ::libc::c_char, >+ ); > pub fn GetProxyHandlerFamily() -> *const c_void; > >- pub fn GetInt8ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut i8); >- pub fn GetUint8ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut u8); >- pub fn GetUint8ClampedArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut u8); >- pub fn GetInt16ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut i16); >- pub fn GetUint16ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut u16); >- pub fn GetInt32ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut i32); >- pub fn GetUint32ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut u32); >- pub fn GetFloat32ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut f32); >- pub fn GetFloat64ArrayLengthAndData(obj: *mut JSObject, >- length: *mut u32, >- isSharedMemory: *mut bool, >- data: *mut *mut f64); >+ pub fn GetInt8ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut i8, >+ ); >+ pub fn GetUint8ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut u8, >+ ); >+ pub fn GetUint8ClampedArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut u8, >+ ); >+ pub fn GetInt16ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut i16, >+ ); >+ pub fn GetUint16ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut u16, >+ ); >+ pub fn GetInt32ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut i32, >+ ); >+ pub fn GetUint32ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut u32, >+ ); >+ pub fn GetFloat32ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut f32, >+ ); >+ pub fn GetFloat64ArrayLengthAndData( >+ obj: *mut JSObject, >+ length: *mut u32, >+ isSharedMemory: *mut bool, >+ data: *mut *mut f64, >+ ); > >- pub fn NewJSAutoStructuredCloneBuffer(scope: JS::StructuredCloneScope, >- callbacks: *const JSStructuredCloneCallbacks) >- -> *mut JSAutoStructuredCloneBuffer; >+ pub fn NewJSAutoStructuredCloneBuffer( >+ scope: JS::StructuredCloneScope, >+ callbacks: *const JSStructuredCloneCallbacks, >+ ) -> *mut JSAutoStructuredCloneBuffer; > pub fn DeleteJSAutoStructuredCloneBuffer(buf: *mut JSAutoStructuredCloneBuffer); > pub fn GetLengthOfJSStructuredCloneData(data: *mut JSStructuredCloneData) -> usize; > pub fn CopyJSStructuredCloneData(src: *mut JSStructuredCloneData, dest: *mut u8); >- pub fn WriteBytesToJSStructuredCloneData(src: *const u8, >- len: usize, >- dest: *mut JSStructuredCloneData) >- -> bool; >+ pub fn WriteBytesToJSStructuredCloneData( >+ src: *const u8, >+ len: usize, >+ dest: *mut JSStructuredCloneData, >+ ) -> bool; > > pub fn IsDebugBuild() -> bool; > } > > #[test] > fn jsglue_cpp_configured_correctly() { > assert_eq!(cfg!(feature = "debugmozjs"), unsafe { IsDebugBuild() }); > } >diff --git a/js/rust/src/heap.rs b/js/rust/src/heap.rs >index 2c2fdd35025c..fc3f43d13a9c 100644 >--- a/js/rust/src/heap.rs >+++ b/js/rust/src/heap.rs >@@ -34,83 +34,80 @@ pub unsafe trait Trace { > #[repr(C)] > #[derive(Debug)] > pub struct Heap<T: GCMethods + Copy> { > ptr: UnsafeCell<T>, > } > > impl<T: GCMethods + Copy> Heap<T> { > pub fn new(v: T) -> Heap<T> >- where Heap<T>: Default >+ where >+ Heap<T>: Default, > { > let ptr = Heap::default(); > ptr.set(v); > ptr > } > > pub fn set(&self, v: T) { > unsafe { > let ptr = self.ptr.get(); > let prev = *ptr; > *ptr = v; > T::post_barrier(ptr, prev, v); > } > } > > pub fn get(&self) -> T { >- unsafe { >- *self.ptr.get() >- } >+ unsafe { *self.ptr.get() } > } > > pub unsafe fn get_unsafe(&self) -> *mut T { > self.ptr.get() > } > > pub fn handle(&self) -> JS::Handle<T> { >- unsafe { >- JS::Handle::from_marked_location(self.ptr.get() as *const _) >- } >+ unsafe { JS::Handle::from_marked_location(self.ptr.get() as *const _) } > } > > pub fn handle_mut(&self) -> JS::MutableHandle<T> { >- unsafe { >- JS::MutableHandle::from_marked_location(self.ptr.get()) >- } >+ unsafe { JS::MutableHandle::from_marked_location(self.ptr.get()) } > } > } > > impl<T: GCMethods + Copy> Clone for Heap<T> >- where Heap<T>: Default >+where >+ Heap<T>: Default, > { > fn clone(&self) -> Self { > Heap::new(self.get()) > } > } > > impl<T: GCMethods + Copy + PartialEq> PartialEq for Heap<T> { > fn eq(&self, other: &Self) -> bool { > self.get() == other.get() > } > } > > impl<T> Default for Heap<*mut T> >- where *mut T: GCMethods + Copy >+where >+ *mut T: GCMethods + Copy, > { > fn default() -> Heap<*mut T> { > Heap { >- ptr: UnsafeCell::new(ptr::null_mut()) >+ ptr: UnsafeCell::new(ptr::null_mut()), > } > } > } > > impl Default for Heap<JS::Value> { > fn default() -> Heap<JS::Value> { > Heap { >- ptr: UnsafeCell::new(JS::Value::default()) >+ ptr: UnsafeCell::new(JS::Value::default()), > } > } > } > > impl<T: GCMethods + Copy> Drop for Heap<T> { > fn drop(&mut self) { > unsafe { > let prev = self.ptr.get(); >@@ -118,17 +115,17 @@ impl<T: GCMethods + Copy> Drop for Heap<T> { > } > } > } > > // Creates a C string literal `$str`. > macro_rules! c_str { > ($str:expr) => { > concat!($str, "\0").as_ptr() as *const ::std::os::raw::c_char >- } >+ }; > } > > unsafe impl Trace for Heap<*mut JSFunction> { > unsafe fn trace(&self, trc: *mut JSTracer) { > glue::CallFunctionTracer(trc, self as *const _ as *mut Self, c_str!("function")); > } > } > >diff --git a/js/rust/src/jsval.rs b/js/rust/src/jsval.rs >index ac9e42647494..f3a388605a03 100644 >--- a/js/rust/src/jsval.rs >+++ b/js/rust/src/jsval.rs >@@ -1,13 +1,12 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this file, > * You can obtain one at http://mozilla.org/MPL/2.0/. */ > >- > use jsapi::root::*; > use libc::c_void; > use std::mem; > > #[cfg(target_pointer_width = "64")] > const JSVAL_TAG_SHIFT: usize = 47; > > #[cfg(target_pointer_width = "64")] >@@ -16,73 +15,70 @@ const JSVAL_TAG_MAX_DOUBLE: u32 = 0x1FFF0u32; > #[cfg(target_pointer_width = "32")] > const JSVAL_TAG_CLEAR: u32 = 0xFFFFFF80; > > #[cfg(target_pointer_width = "64")] > #[repr(u32)] > #[allow(dead_code)] > #[derive(Clone, Copy, Debug)] > enum ValueTag { >- INT32 = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_INT32 as u32), >+ INT32 = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_INT32 as u32), > UNDEFINED = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_UNDEFINED as u32), >- STRING = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_STRING as u32), >- SYMBOL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_SYMBOL as u32), >+ STRING = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_STRING as u32), >+ SYMBOL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_SYMBOL as u32), > #[cfg(feature = "bigint")] >- BIGINT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BIGINT as u32), >- BOOLEAN = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BOOLEAN as u32), >- MAGIC = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_MAGIC as u32), >- NULL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_NULL as u32), >- OBJECT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_OBJECT as u32), >+ BIGINT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BIGINT as u32), >+ BOOLEAN = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_BOOLEAN as u32), >+ MAGIC = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_MAGIC as u32), >+ NULL = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_NULL as u32), >+ OBJECT = JSVAL_TAG_MAX_DOUBLE | (JSValueType::JSVAL_TYPE_OBJECT as u32), > } > > #[cfg(target_pointer_width = "32")] > #[repr(u32)] > #[allow(dead_code)] > #[derive(Clone, Copy, Debug)] > enum ValueTag { >- PRIVATE = 0, >- INT32 = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_INT32 as u32), >+ PRIVATE = 0, >+ INT32 = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_INT32 as u32), > UNDEFINED = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_UNDEFINED as u32), >- STRING = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_STRING as u32), >- SYMBOL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_SYMBOL as u32), >+ STRING = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_STRING as u32), >+ SYMBOL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_SYMBOL as u32), > #[cfg(feature = "bigint")] >- BIGINT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BIGINT as u32), >- BOOLEAN = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BOOLEAN as u32), >- MAGIC = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_MAGIC as u32), >- NULL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_NULL as u32), >- OBJECT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_OBJECT as u32), >+ BIGINT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BIGINT as u32), >+ BOOLEAN = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_BOOLEAN as u32), >+ MAGIC = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_MAGIC as u32), >+ NULL = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_NULL as u32), >+ OBJECT = JSVAL_TAG_CLEAR as u32 | (JSValueType::JSVAL_TYPE_OBJECT as u32), > } > > #[cfg(target_pointer_width = "64")] > #[repr(u64)] > #[allow(dead_code)] > #[derive(Clone, Copy, Debug)] > enum ValueShiftedTag { > MAX_DOUBLE = (((JSVAL_TAG_MAX_DOUBLE as u64) << JSVAL_TAG_SHIFT) | 0xFFFFFFFFu64), >- INT32 = ((ValueTag::INT32 as u64) << JSVAL_TAG_SHIFT), >- UNDEFINED = ((ValueTag::UNDEFINED as u64) << JSVAL_TAG_SHIFT), >- STRING = ((ValueTag::STRING as u64) << JSVAL_TAG_SHIFT), >- SYMBOL = ((ValueTag::SYMBOL as u64) << JSVAL_TAG_SHIFT), >+ INT32 = ((ValueTag::INT32 as u64) << JSVAL_TAG_SHIFT), >+ UNDEFINED = ((ValueTag::UNDEFINED as u64) << JSVAL_TAG_SHIFT), >+ STRING = ((ValueTag::STRING as u64) << JSVAL_TAG_SHIFT), >+ SYMBOL = ((ValueTag::SYMBOL as u64) << JSVAL_TAG_SHIFT), > #[cfg(feature = "bigint")] >- BIGINT = ((ValueTag::BIGINT as u64) << JSVAL_TAG_SHIFT), >- BOOLEAN = ((ValueTag::BOOLEAN as u64) << JSVAL_TAG_SHIFT), >- MAGIC = ((ValueTag::MAGIC as u64) << JSVAL_TAG_SHIFT), >- NULL = ((ValueTag::NULL as u64) << JSVAL_TAG_SHIFT), >- OBJECT = ((ValueTag::OBJECT as u64) << JSVAL_TAG_SHIFT), >+ BIGINT = ((ValueTag::BIGINT as u64) << JSVAL_TAG_SHIFT), >+ BOOLEAN = ((ValueTag::BOOLEAN as u64) << JSVAL_TAG_SHIFT), >+ MAGIC = ((ValueTag::MAGIC as u64) << JSVAL_TAG_SHIFT), >+ NULL = ((ValueTag::NULL as u64) << JSVAL_TAG_SHIFT), >+ OBJECT = ((ValueTag::OBJECT as u64) << JSVAL_TAG_SHIFT), > } > >- > #[cfg(target_pointer_width = "64")] > const JSVAL_PAYLOAD_MASK: u64 = 0x00007FFFFFFFFFFF; > > #[inline(always)] > fn AsJSVal(val: u64) -> JS::Value { >- JS::Value { >- asBits_: val, >- } >+ JS::Value { asBits_: val } > } > > #[cfg(target_pointer_width = "64")] > #[inline(always)] > fn BuildJSVal(tag: ValueTag, payload: u64) -> JS::Value { > AsJSVal(((tag as u32 as u64) << JSVAL_TAG_SHIFT) | payload) > } > >@@ -214,225 +210,177 @@ impl JS::Value { > #[inline(always)] > unsafe fn asBits(&self) -> u64 { > self.asBits_ > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_undefined(&self) -> bool { >- unsafe { >- self.asBits() == ValueShiftedTag::UNDEFINED as u64 >- } >+ unsafe { self.asBits() == ValueShiftedTag::UNDEFINED as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_undefined(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::UNDEFINED as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::UNDEFINED as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_null(&self) -> bool { >- unsafe { >- self.asBits() == ValueShiftedTag::NULL as u64 >- } >+ unsafe { self.asBits() == ValueShiftedTag::NULL as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_null(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::NULL as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::NULL as u64 } > } > > #[inline(always)] > pub fn is_null_or_undefined(&self) -> bool { > self.is_null() || self.is_undefined() > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_boolean(&self) -> bool { >- unsafe { >- (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BOOLEAN as u64 >- } >+ unsafe { (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BOOLEAN as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_boolean(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::BOOLEAN as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::BOOLEAN as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_int32(&self) -> bool { >- unsafe { >- (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::INT32 as u64 >- } >+ unsafe { (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::INT32 as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_int32(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::INT32 as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::INT32 as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_double(&self) -> bool { >- unsafe { >- self.asBits() <= ValueShiftedTag::MAX_DOUBLE as u64 >- } >+ unsafe { self.asBits() <= ValueShiftedTag::MAX_DOUBLE as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_double(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) <= JSVAL_TAG_CLEAR as u64 >- } >+ unsafe { (self.asBits() >> 32) <= JSVAL_TAG_CLEAR as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_number(&self) -> bool { > const JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET: u64 = ValueShiftedTag::UNDEFINED as u64; >- unsafe { >- self.asBits() < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET >- } >+ unsafe { self.asBits() < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_NUMBER_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_number(&self) -> bool { > const JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET: u64 = ValueTag::INT32 as u64; >- unsafe { >- (self.asBits() >> 32) <= JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET >- } >+ unsafe { (self.asBits() >> 32) <= JSVAL_UPPER_INCL_TAG_OF_NUMBER_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_primitive(&self) -> bool { > const JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET: u64 = ValueShiftedTag::OBJECT as u64; >- unsafe { >- self.asBits() < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET >- } >+ unsafe { self.asBits() < JSVAL_UPPER_EXCL_SHIFTED_TAG_OF_PRIMITIVE_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_primitive(&self) -> bool { > const JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET: u64 = ValueTag::OBJECT as u64; >- unsafe { >- (self.asBits() >> 32) < JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET >- } >+ unsafe { (self.asBits() >> 32) < JSVAL_UPPER_EXCL_TAG_OF_PRIMITIVE_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_string(&self) -> bool { >- unsafe { >- (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::STRING as u64 >- } >+ unsafe { (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::STRING as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_string(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::STRING as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::STRING as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_object(&self) -> bool { > unsafe { > assert!((self.asBits() >> JSVAL_TAG_SHIFT) <= ValueTag::OBJECT as u64); > self.asBits() >= ValueShiftedTag::OBJECT as u64 > } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_object(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::OBJECT as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::OBJECT as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_symbol(&self) -> bool { >- unsafe { >- (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::SYMBOL as u64 >- } >+ unsafe { (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::SYMBOL as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_symbol(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::SYMBOL as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::SYMBOL as u64 } > } > > #[inline(always)] > #[cfg(feature = "bigint")] > #[cfg(target_pointer_width = "64")] > pub fn is_bigint(&self) -> bool { >- unsafe { >- (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BIGINT as u64 >- } >+ unsafe { (self.asBits() >> JSVAL_TAG_SHIFT) == ValueTag::BIGINT as u64 } > } > > #[inline(always)] > #[cfg(feature = "bigint")] > #[cfg(target_pointer_width = "32")] > pub fn is_bigint(&self) -> bool { >- unsafe { >- (self.asBits() >> 32) == ValueTag::BIGINT as u64 >- } >+ unsafe { (self.asBits() >> 32) == ValueTag::BIGINT as u64 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn to_boolean(&self) -> bool { > assert!(self.is_boolean()); >- unsafe { >- (self.asBits() & JSVAL_PAYLOAD_MASK) != 0 >- } >+ unsafe { (self.asBits() & JSVAL_PAYLOAD_MASK) != 0 } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn to_boolean(&self) -> bool { > assert!(self.is_boolean()); >- unsafe { >- (self.asBits() & 0x00000000FFFFFFFF) != 0 >- } >+ unsafe { (self.asBits() & 0x00000000FFFFFFFF) != 0 } > } > > #[inline(always)] > pub fn to_int32(&self) -> i32 { > assert!(self.is_int32()); >- unsafe { >- (self.asBits() & 0x00000000FFFFFFFF) as i32 >- } >+ unsafe { (self.asBits() & 0x00000000FFFFFFFF) as i32 } > } > > #[inline(always)] > pub fn to_double(&self) -> f64 { > assert!(self.is_double()); > unsafe { mem::transmute(self.asBits()) } > } > >@@ -531,28 +479,24 @@ impl JS::Value { > ptrBits as *const c_void > } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn is_gcthing(&self) -> bool { > const JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET: u64 = ValueShiftedTag::STRING as u64; >- unsafe { >- self.asBits() >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET >- } >+ unsafe { self.asBits() >= JSVAL_LOWER_INCL_SHIFTED_TAG_OF_GCTHING_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "32")] > pub fn is_gcthing(&self) -> bool { > const JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET: u64 = ValueTag::STRING as u64; >- unsafe { >- (self.asBits() >> 32) >= JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET >- } >+ unsafe { (self.asBits() >> 32) >= JSVAL_LOWER_INCL_TAG_OF_GCTHING_SET } > } > > #[inline(always)] > #[cfg(target_pointer_width = "64")] > pub fn to_gcthing(&self) -> *mut c_void { > assert!(self.is_gcthing()); > unsafe { > let ptrBits = self.asBits() & JSVAL_PAYLOAD_MASK; >diff --git a/js/rust/src/lib.rs b/js/rust/src/lib.rs >index f8df9ea31d60..453078647c97 100644 >--- a/js/rust/src/lib.rs >+++ b/js/rust/src/lib.rs >@@ -1,18 +1,21 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this file, > * You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #![crate_name = "js"] > #![crate_type = "rlib"] >- > #![cfg_attr(feature = "nonzero", feature(nonzero))] >- >-#![allow(non_upper_case_globals, non_camel_case_types, non_snake_case, improper_ctypes)] >+#![allow( >+ non_upper_case_globals, >+ non_camel_case_types, >+ non_snake_case, >+ improper_ctypes >+)] > > #[cfg(feature = "nonzero")] > extern crate core; > #[macro_use] > extern crate lazy_static; > extern crate libc; > #[macro_use] > extern crate log; >diff --git a/js/rust/src/panic.rs b/js/rust/src/panic.rs >index 351e24f77350..496ed9b33d4d 100644 >--- a/js/rust/src/panic.rs >+++ b/js/rust/src/panic.rs >@@ -1,28 +1,29 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > use std::any::Any; > use std::cell::RefCell; >-use std::panic::{UnwindSafe, catch_unwind, resume_unwind}; >+use std::panic::{catch_unwind, resume_unwind, UnwindSafe}; > > thread_local!(static PANIC_RESULT: RefCell<Option<Box<Any + Send>>> = RefCell::new(None)); > > /// If there is a pending panic, resume unwinding. > pub fn maybe_resume_unwind() { > if let Some(error) = PANIC_RESULT.with(|result| result.borrow_mut().take()) { > resume_unwind(error); > } > } > > /// Generic wrapper for JS engine callbacks panic-catching > pub fn wrap_panic<F, R>(function: F, generic_return_type: R) -> R >- where F: FnOnce() -> R + UnwindSafe >+where >+ F: FnOnce() -> R + UnwindSafe, > { > let result = catch_unwind(function); > match result { > Ok(result) => result, > Err(error) => { > PANIC_RESULT.with(|result| { > assert!(result.borrow().is_none()); > *result.borrow_mut() = Some(error); >diff --git a/js/rust/src/rust.rs b/js/rust/src/rust.rs >index 69993caac787..1bb530550731 100644 >--- a/js/rust/src/rust.rs >+++ b/js/rust/src/rust.rs >@@ -1,36 +1,39 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this file, > * You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Rust wrappers around the raw JS apis > > use ac::AutoCompartment; >+use glue::{ >+ AppendToAutoObjectVector, CreateAutoObjectVector, CreateCallArgsFromVp, DeleteAutoObjectVector, >+ IsDebugBuild, >+}; >+use glue::{CreateAutoIdVector, DestroyAutoIdVector, SliceAutoIdVector}; >+use glue::{DeleteCompileOptions, NewCompileOptions}; >+use jsapi::root::*; >+use jsval::{self, UndefinedValue}; > use libc::c_uint; >+use panic; > use std::cell::{Cell, UnsafeCell}; > use std::char; >-use std::ffi; >-use std::ptr; >-use std::slice; >-use std::mem; >-use std::u32; > use std::default::Default; >+use std::ffi; > use std::marker; >+use std::mem; > use std::ops::{Deref, DerefMut}; >-use std::sync::{Once, ONCE_INIT, Arc, Mutex}; >+use std::ptr; >+use std::slice; > use std::sync::atomic::{AtomicBool, AtomicPtr, AtomicUsize, Ordering}; >-use std::sync::mpsc::{SyncSender, sync_channel}; >+use std::sync::mpsc::{sync_channel, SyncSender}; >+use std::sync::{Arc, Mutex, Once, ONCE_INIT}; > use std::thread; >-use jsapi::root::*; >-use jsval::{self, UndefinedValue}; >-use glue::{CreateAutoObjectVector, CreateCallArgsFromVp, AppendToAutoObjectVector, DeleteAutoObjectVector, IsDebugBuild}; >-use glue::{CreateAutoIdVector, SliceAutoIdVector, DestroyAutoIdVector}; >-use glue::{NewCompileOptions, DeleteCompileOptions}; >-use panic; >+use std::u32; > > const DEFAULT_HEAPSIZE: u32 = 32_u32 * 1024_u32 * 1024_u32; > > // From Gecko: > // Our "default" stack is what we use in configurations where we don't have a compelling reason to > // do things differently. This is effectively 1MB on 64-bit platforms. > const STACK_QUOTA: usize = 128 * 8 * 1024; > >@@ -72,19 +75,17 @@ lazy_static! { > /// A wrapper for the `JSContext` structure in SpiderMonkey. > pub struct Runtime { > cx: *mut JSContext, > } > > impl Runtime { > /// Get the `JSContext` for this thread. > pub fn get() -> *mut JSContext { >- let cx = CONTEXT.with(|context| { >- context.get() >- }); >+ let cx = CONTEXT.with(|context| context.get()); > assert!(!cx.is_null()); > cx > } > > /// Creates a new `JSContext`. > /// > /// * `use_internal_job_queue`: If `true`, then SpiderMonkey's internal > /// micro-task job queue is used. If `false`, then it is up to you to >@@ -107,19 +108,17 @@ impl Runtime { > assert_eq!(self.get(), val); > } > > fn get(&self) -> *mut JSContext { > self.as_atomic().load(Ordering::SeqCst) > } > > fn as_atomic(&self) -> &AtomicPtr<JSContext> { >- unsafe { >- mem::transmute(&self.0) >- } >+ unsafe { mem::transmute(&self.0) } > } > } > > lazy_static! { > static ref PARENT: Parent = Parent(UnsafeCell::new(0 as *mut _)); > } > static ONCE: Once = ONCE_INIT; > >@@ -127,22 +126,24 @@ impl Runtime { > // There is a 1:1 relationship between threads and JSContexts, > // so we must spawn a new thread for the parent context. > let (tx, rx) = sync_channel(0); > *SHUT_DOWN_SIGNAL.lock().unwrap() = Some(tx); > let _ = thread::spawn(move || { > let is_debug_mozjs = cfg!(feature = "debugmozjs"); > let diagnostic = JS::detail::InitWithFailureDiagnostic(is_debug_mozjs); > if !diagnostic.is_null() { >- panic!("JS::detail::InitWithFailureDiagnostic failed: {}", >- ffi::CStr::from_ptr(diagnostic).to_string_lossy()); >+ panic!( >+ "JS::detail::InitWithFailureDiagnostic failed: {}", >+ ffi::CStr::from_ptr(diagnostic).to_string_lossy() >+ ); > } > >- let context = JS_NewContext( >- DEFAULT_HEAPSIZE, ChunkSize as u32, ptr::null_mut()); >+ let context = >+ JS_NewContext(DEFAULT_HEAPSIZE, ChunkSize as u32, ptr::null_mut()); > assert!(!context.is_null()); > JS::InitSelfHostedCode(context); > PARENT.set(context); > > // The last JSRuntime child died, resume the execution by destroying the parent. > rx.recv().unwrap(); > let cx = PARENT.get(); > JS_DestroyContext(cx); >@@ -154,34 +155,36 @@ impl Runtime { > > while PARENT.get().is_null() { > thread::yield_now(); > } > }); > > assert_eq!(IsDebugBuild(), cfg!(feature = "debugmozjs")); > >- let js_context = JS_NewContext(DEFAULT_HEAPSIZE, >- ChunkSize as u32, >- JS_GetParentRuntime(PARENT.get())); >+ let js_context = JS_NewContext( >+ DEFAULT_HEAPSIZE, >+ ChunkSize as u32, >+ JS_GetParentRuntime(PARENT.get()), >+ ); > assert!(!js_context.is_null()); > > // Unconstrain the runtime's threshold on nominal heap size, to avoid > // triggering GC too often if operating continuously near an arbitrary > // finite threshold. This leaves the maximum-JS_malloc-bytes threshold > // still in effect to cause periodical, and we hope hygienic, > // last-ditch GCs from within the GC's allocator. >- JS_SetGCParameter( >- js_context, JSGCParamKey::JSGC_MAX_BYTES, u32::MAX); >+ JS_SetGCParameter(js_context, JSGCParamKey::JSGC_MAX_BYTES, u32::MAX); > > JS_SetNativeStackQuota( > js_context, > STACK_QUOTA, > STACK_QUOTA - SYSTEM_CODE_BUFFER, >- STACK_QUOTA - SYSTEM_CODE_BUFFER - TRUSTED_SCRIPT_BUFFER); >+ STACK_QUOTA - SYSTEM_CODE_BUFFER - TRUSTED_SCRIPT_BUFFER, >+ ); > > let opts = JS::ContextOptionsRef(js_context); > (*opts).set_baseline_(true); > (*opts).set_ion_(true); > (*opts).set_nativeRegExp_(true); > > CONTEXT.with(|context| { > assert!(context.get().is_null()); >@@ -193,56 +196,60 @@ impl Runtime { > } > > JS::InitSelfHostedCode(js_context); > > JS::SetWarningReporter(js_context, Some(report_warning)); > > JS_BeginRequest(js_context); > >- Ok(Runtime { >- cx: js_context, >- }) >+ Ok(Runtime { cx: js_context }) > } > } > > /// Returns the underlying `JSContext` object. > pub fn cx(&self) -> *mut JSContext { > self.cx > } > > /// Returns the underlying `JSContext`'s `JSRuntime`. > pub fn rt(&self) -> *mut JSRuntime { >- unsafe { >- JS_GetRuntime(self.cx) >- } >+ unsafe { JS_GetRuntime(self.cx) } > } > >- pub fn evaluate_script(&self, glob: JS::HandleObject, script: &str, filename: &str, >- line_num: u32, rval: JS::MutableHandleValue) >- -> Result<(),()> { >+ pub fn evaluate_script( >+ &self, >+ glob: JS::HandleObject, >+ script: &str, >+ filename: &str, >+ line_num: u32, >+ rval: JS::MutableHandleValue, >+ ) -> Result<(), ()> { > let script_utf16: Vec<u16> = script.encode_utf16().collect(); > let filename_cstr = ffi::CString::new(filename.as_bytes()).unwrap(); >- debug!("Evaluating script from {} with content {}", filename, script); >+ debug!( >+ "Evaluating script from {} with content {}", >+ filename, script >+ ); > // SpiderMonkey does not approve of null pointers. > let (ptr, len) = if script_utf16.len() == 0 { > static empty: &'static [u16] = &[]; > (empty.as_ptr(), 0) > } else { > (script_utf16.as_ptr(), script_utf16.len() as c_uint) > }; > assert!(!ptr.is_null()); > unsafe { > let _ac = AutoCompartment::with_obj(self.cx(), glob.get()); > let options = CompileOptionsWrapper::new(self.cx(), filename_cstr.as_ptr(), line_num); > > let mut srcBuf = JS::SourceBufferHolder { > data_: ptr, > length_: len as _, >- ownsChars_: false >+ ownsChars_: false, > }; > if !JS::Evaluate(self.cx(), options.ptr, &mut srcBuf, rval) { > debug!("...err!"); > panic::maybe_resume_unwind(); > Err(()) > } else { > // we could return the script result but then we'd have > // to root it and so forth and, really, who cares? >@@ -283,87 +290,109 @@ impl Drop for Runtime { > > pub trait RootKind { > #[inline(always)] > fn rootKind() -> JS::RootKind; > } > > impl RootKind for *mut JSObject { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Object } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Object >+ } > } > > impl RootKind for *mut JSFlatString { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::String } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::String >+ } > } > > impl RootKind for *mut JSFunction { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Object } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Object >+ } > } > > impl RootKind for *mut JSString { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::String } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::String >+ } > } > > impl RootKind for *mut JS::Symbol { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Symbol } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Symbol >+ } > } > > #[cfg(feature = "bigint")] > impl RootKind for *mut JS::BigInt { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::BigInt } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::BigInt >+ } > } > > impl RootKind for *mut JSScript { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Script } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Script >+ } > } > > impl RootKind for jsid { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Id } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Id >+ } > } > > impl RootKind for JS::Value { > #[inline(always)] >- fn rootKind() -> JS::RootKind { JS::RootKind::Value } >+ fn rootKind() -> JS::RootKind { >+ JS::RootKind::Value >+ } > } > > impl<T> JS::Rooted<T> { > pub fn new_unrooted() -> JS::Rooted<T> >- where T: GCMethods, >+ where >+ T: GCMethods, > { > JS::Rooted { > stack: ptr::null_mut(), > prev: ptr::null_mut(), > ptr: unsafe { T::initial() }, > _phantom_0: marker::PhantomData, > } > } > > unsafe fn get_rooting_context(cx: *mut JSContext) -> *mut JS::RootingContext { > mem::transmute(cx) > } > >- unsafe fn get_root_stack(cx: *mut JSContext) >- -> *mut *mut JS::Rooted<*mut ::std::os::raw::c_void> >- where T: RootKind >+ unsafe fn get_root_stack( >+ cx: *mut JSContext, >+ ) -> *mut *mut JS::Rooted<*mut ::std::os::raw::c_void> >+ where >+ T: RootKind, > { > let kind = T::rootKind() as usize; > let rooting_cx = Self::get_rooting_context(cx); > &mut rooting_cx.as_mut().unwrap().stackRoots_[kind] as *mut _ as *mut _ > } > > pub unsafe fn register_with_root_lists(&mut self, cx: *mut JSContext) >- where T: RootKind >+ where >+ T: RootKind, > { > self.stack = Self::get_root_stack(cx); > let stack = self.stack.as_mut().unwrap(); > self.prev = *stack as *mut _; > > *stack = self as *mut _ as usize as _; > } > >@@ -372,43 +401,40 @@ impl<T> JS::Rooted<T> { > *self.stack = self.prev; > } > } > > /// Rust API for keeping a JS::Rooted value in the context's root stack. > /// Example usage: `rooted!(in(cx) let x = UndefinedValue());`. > /// `RootedGuard::new` also works, but the macro is preferred. > pub struct RootedGuard<'a, T: 'a + RootKind + GCMethods> { >- root: &'a mut JS::Rooted<T> >+ root: &'a mut JS::Rooted<T>, > } > > impl<'a, T: 'a + RootKind + GCMethods> RootedGuard<'a, T> { > pub fn new(cx: *mut JSContext, root: &'a mut JS::Rooted<T>, initial: T) -> Self { > root.ptr = initial; > unsafe { > root.register_with_root_lists(cx); > } >- RootedGuard { >- root: root >- } >+ RootedGuard { root: root } > } > > pub fn handle(&self) -> JS::Handle<T> { >- unsafe { >- JS::Handle::from_marked_location(&self.root.ptr) >- } >+ unsafe { JS::Handle::from_marked_location(&self.root.ptr) } > } > > pub fn handle_mut(&mut self) -> JS::MutableHandle<T> { >- unsafe { >- JS::MutableHandle::from_marked_location(&mut self.root.ptr) >- } >+ unsafe { JS::MutableHandle::from_marked_location(&mut self.root.ptr) } > } > >- pub fn get(&self) -> T where T: Copy { >+ pub fn get(&self) -> T >+ where >+ T: Copy, >+ { > self.root.ptr > } > > pub fn set(&mut self, v: T) { > self.root.ptr = v; > } > } > >@@ -438,22 +464,23 @@ impl<'a, T: 'a + RootKind + GCMethods> Drop for RootedGuard<'a, T> { > macro_rules! rooted { > (in($cx:expr) let $name:ident = $init:expr) => { > let mut __root = $crate::jsapi::JS::Rooted::new_unrooted(); > let $name = $crate::rust::RootedGuard::new($cx, &mut __root, $init); > }; > (in($cx:expr) let mut $name:ident = $init:expr) => { > let mut __root = $crate::jsapi::JS::Rooted::new_unrooted(); > let mut $name = $crate::rust::RootedGuard::new($cx, &mut __root, $init); >- } >+ }; > } > > impl<T> JS::Handle<T> { > pub fn get(&self) -> T >- where T: Copy >+ where >+ T: Copy, > { > unsafe { *self.ptr } > } > > pub unsafe fn from_marked_location(ptr: *const T) -> JS::Handle<T> { > JS::Handle { > ptr: mem::transmute(ptr), > _phantom_0: marker::PhantomData, >@@ -473,29 +500,29 @@ impl<T> JS::MutableHandle<T> { > pub unsafe fn from_marked_location(ptr: *mut T) -> JS::MutableHandle<T> { > JS::MutableHandle { > ptr: ptr, > _phantom_0: marker::PhantomData, > } > } > > pub fn handle(&self) -> JS::Handle<T> { >- unsafe { >- JS::Handle::from_marked_location(self.ptr as *const _) >- } >+ unsafe { JS::Handle::from_marked_location(self.ptr as *const _) } > } > > pub fn get(&self) -> T >- where T: Copy >+ where >+ T: Copy, > { > unsafe { *self.ptr } > } > > pub fn set(&self, v: T) >- where T: Copy >+ where >+ T: Copy, > { > unsafe { *self.ptr = v } > } > } > > impl<T> Deref for JS::MutableHandle<T> { > type Target = T; > >@@ -507,127 +534,139 @@ impl<T> Deref for JS::MutableHandle<T> { > impl<T> DerefMut for JS::MutableHandle<T> { > fn deref_mut<'a>(&'a mut self) -> &'a mut T { > unsafe { &mut *self.ptr } > } > } > > impl JS::HandleValue { > pub fn null() -> JS::HandleValue { >- unsafe { >- JS::NullHandleValue >- } >+ unsafe { JS::NullHandleValue } > } > > pub fn undefined() -> JS::HandleValue { >- unsafe { >- JS::UndefinedHandleValue >- } >+ unsafe { JS::UndefinedHandleValue } > } > } > > impl JS::HandleValueArray { > pub fn new() -> JS::HandleValueArray { > JS::HandleValueArray { > length_: 0, > elements_: ptr::null(), > } > } > > pub unsafe fn from_rooted_slice(values: &[JS::Value]) -> JS::HandleValueArray { > JS::HandleValueArray { > length_: values.len(), >- elements_: values.as_ptr() >+ elements_: values.as_ptr(), > } > } > } > > const ConstNullValue: *mut JSObject = 0 as *mut JSObject; > > impl JS::HandleObject { > pub fn null() -> JS::HandleObject { >- unsafe { >- JS::HandleObject::from_marked_location(&ConstNullValue) >- } >+ unsafe { JS::HandleObject::from_marked_location(&ConstNullValue) } > } > } > > impl Default for jsid { > fn default() -> jsid { > jsid { > asBits: JSID_TYPE_VOID as usize, > } > } > } > > impl Default for JS::Value { >- fn default() -> JS::Value { jsval::UndefinedValue() } >+ fn default() -> JS::Value { >+ jsval::UndefinedValue() >+ } > } > > impl Default for JS::RealmOptions { >- fn default() -> Self { unsafe { ::std::mem::zeroed() } } >+ fn default() -> Self { >+ unsafe { ::std::mem::zeroed() } >+ } > } > > const ChunkShift: usize = 20; > const ChunkSize: usize = 1 << ChunkShift; > > #[cfg(target_pointer_width = "32")] > const ChunkLocationOffset: usize = ChunkSize - 2 * 4 - 8; > > pub trait GCMethods { > unsafe fn initial() -> Self; > unsafe fn post_barrier(v: *mut Self, prev: Self, next: Self); > } > > impl GCMethods for jsid { >- unsafe fn initial() -> jsid { Default::default() } >+ unsafe fn initial() -> jsid { >+ Default::default() >+ } > unsafe fn post_barrier(_: *mut jsid, _: jsid, _: jsid) {} > } > > impl GCMethods for *mut JSObject { >- unsafe fn initial() -> *mut JSObject { ptr::null_mut() } >- unsafe fn post_barrier(v: *mut *mut JSObject, >- prev: *mut JSObject, next: *mut JSObject) { >+ unsafe fn initial() -> *mut JSObject { >+ ptr::null_mut() >+ } >+ unsafe fn post_barrier(v: *mut *mut JSObject, prev: *mut JSObject, next: *mut JSObject) { > JS::HeapObjectPostBarrier(v, prev, next); > } > } > > impl GCMethods for *mut JSString { >- unsafe fn initial() -> *mut JSString { ptr::null_mut() } >+ unsafe fn initial() -> *mut JSString { >+ ptr::null_mut() >+ } > unsafe fn post_barrier(_: *mut *mut JSString, _: *mut JSString, _: *mut JSString) {} > } > > impl GCMethods for *mut JSScript { >- unsafe fn initial() -> *mut JSScript { ptr::null_mut() } >- unsafe fn post_barrier(_: *mut *mut JSScript, _: *mut JSScript, _: *mut JSScript) { } >+ unsafe fn initial() -> *mut JSScript { >+ ptr::null_mut() >+ } >+ unsafe fn post_barrier(_: *mut *mut JSScript, _: *mut JSScript, _: *mut JSScript) {} > } > > impl GCMethods for *mut JSFunction { >- unsafe fn initial() -> *mut JSFunction { ptr::null_mut() } >- unsafe fn post_barrier(v: *mut *mut JSFunction, >- prev: *mut JSFunction, next: *mut JSFunction) { >- JS::HeapObjectPostBarrier(mem::transmute(v), >- mem::transmute(prev), >- mem::transmute(next)); >+ unsafe fn initial() -> *mut JSFunction { >+ ptr::null_mut() >+ } >+ unsafe fn post_barrier(v: *mut *mut JSFunction, prev: *mut JSFunction, next: *mut JSFunction) { >+ JS::HeapObjectPostBarrier( >+ mem::transmute(v), >+ mem::transmute(prev), >+ mem::transmute(next), >+ ); > } > } > > impl GCMethods for JS::Value { >- unsafe fn initial() -> JS::Value { UndefinedValue() } >+ unsafe fn initial() -> JS::Value { >+ UndefinedValue() >+ } > unsafe fn post_barrier(v: *mut JS::Value, prev: JS::Value, next: JS::Value) { > JS::HeapValuePostBarrier(v, &prev, &next); > } > } > > // ___________________________________________________________________________ > // Implementations for various things in jsapi.rs > > impl Drop for JSAutoRealmAllowCCW { > fn drop(&mut self) { >- unsafe { JS::LeaveRealm(self.cx_, self.oldRealm_); } >+ unsafe { >+ JS::LeaveRealm(self.cx_, self.oldRealm_); >+ } > } > } > > impl JSJitMethodCallArgs { > #[inline] > pub fn get(&self, i: u32) -> JS::HandleValue { > unsafe { > if i < self._base.argc_ { >@@ -636,104 +675,89 @@ impl JSJitMethodCallArgs { > JS::UndefinedHandleValue > } > } > } > > #[inline] > pub fn index(&self, i: u32) -> JS::HandleValue { > assert!(i < self._base.argc_); >- unsafe { >- JS::HandleValue::from_marked_location(self._base.argv_.offset(i as isize)) >- } >+ unsafe { JS::HandleValue::from_marked_location(self._base.argv_.offset(i as isize)) } > } > > #[inline] > pub fn index_mut(&self, i: u32) -> JS::MutableHandleValue { > assert!(i < self._base.argc_); >- unsafe { >- JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(i as isize)) >- } >+ unsafe { JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(i as isize)) } > } > > #[inline] > pub fn rval(&self) -> JS::MutableHandleValue { >- unsafe { >- JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(-2)) >- } >+ unsafe { JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(-2)) } > } > } > > // XXX need to hack up bindgen to convert this better so we don't have > // to duplicate so much code here > impl JS::CallArgs { > #[inline] > pub unsafe fn from_vp(vp: *mut JS::Value, argc: u32) -> JS::CallArgs { > CreateCallArgsFromVp(argc, vp) > } > > #[inline] > pub fn index(&self, i: u32) -> JS::HandleValue { > assert!(i < self._base.argc_); >- unsafe { >- JS::HandleValue::from_marked_location(self._base.argv_.offset(i as isize)) >- } >+ unsafe { JS::HandleValue::from_marked_location(self._base.argv_.offset(i as isize)) } > } > > #[inline] > pub fn index_mut(&self, i: u32) -> JS::MutableHandleValue { > assert!(i < self._base.argc_); >- unsafe { >- JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(i as isize)) >- } >+ unsafe { JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(i as isize)) } > } > > #[inline] > pub fn get(&self, i: u32) -> JS::HandleValue { > unsafe { > if i < self._base.argc_ { > JS::HandleValue::from_marked_location(self._base.argv_.offset(i as isize)) > } else { > JS::UndefinedHandleValue > } > } > } > > #[inline] > pub fn rval(&self) -> JS::MutableHandleValue { >- unsafe { >- JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(-2)) >- } >+ unsafe { JS::MutableHandleValue::from_marked_location(self._base.argv_.offset(-2)) } > } > > #[inline] > pub fn thisv(&self) -> JS::HandleValue { >- unsafe { >- JS::HandleValue::from_marked_location(self._base.argv_.offset(-1)) >- } >+ unsafe { JS::HandleValue::from_marked_location(self._base.argv_.offset(-1)) } > } > > #[inline] > pub fn calleev(&self) -> JS::HandleValue { >- unsafe { >- JS::HandleValue::from_marked_location(self._base.argv_.offset(-2)) >- } >+ unsafe { JS::HandleValue::from_marked_location(self._base.argv_.offset(-2)) } > } > > #[inline] > pub fn callee(&self) -> *mut JSObject { > self.calleev().to_object() > } > > #[inline] > pub fn new_target(&self) -> JS::MutableHandleValue { > assert!(self._base.constructing_()); > unsafe { > JS::MutableHandleValue::from_marked_location( >- self._base.argv_.offset(self._base.argc_ as isize)) >+ self._base.argv_.offset(self._base.argc_ as isize), >+ ) > } > } > } > > impl JSJitGetterCallArgs { > #[inline] > pub fn rval(&self) -> JS::MutableHandleValue { > self._base >@@ -747,49 +771,49 @@ impl JSJitSetterCallArgs { > self._base.handle() > } > } > > // ___________________________________________________________________________ > // Wrappers around things in jsglue.cpp > > pub struct AutoObjectVectorWrapper { >- pub ptr: *mut JS::AutoObjectVector >+ pub ptr: *mut JS::AutoObjectVector, > } > > impl AutoObjectVectorWrapper { > pub fn new(cx: *mut JSContext) -> AutoObjectVectorWrapper { > AutoObjectVectorWrapper { >- ptr: unsafe { >- CreateAutoObjectVector(cx) >- } >+ ptr: unsafe { CreateAutoObjectVector(cx) }, > } > } > > pub fn append(&self, obj: *mut JSObject) -> bool { >- unsafe { >- AppendToAutoObjectVector(self.ptr, obj) >- } >+ unsafe { AppendToAutoObjectVector(self.ptr, obj) } > } > } > > impl Drop for AutoObjectVectorWrapper { > fn drop(&mut self) { > unsafe { DeleteAutoObjectVector(self.ptr) } > } > } > > pub struct CompileOptionsWrapper { >- pub ptr: *mut JS::ReadOnlyCompileOptions >+ pub ptr: *mut JS::ReadOnlyCompileOptions, > } > > impl CompileOptionsWrapper { >- pub fn new(cx: *mut JSContext, file: *const ::libc::c_char, line: c_uint) -> CompileOptionsWrapper { >+ pub fn new( >+ cx: *mut JSContext, >+ file: *const ::libc::c_char, >+ line: c_uint, >+ ) -> CompileOptionsWrapper { > CompileOptionsWrapper { >- ptr: unsafe { NewCompileOptions(cx, file, line) } >+ ptr: unsafe { NewCompileOptions(cx, file, line) }, > } > } > } > > impl Drop for CompileOptionsWrapper { > fn drop(&mut self) { > unsafe { DeleteCompileOptions(self.ptr) } > } >@@ -840,19 +864,18 @@ pub unsafe fn ToNumber(cx: *mut JSContext, v: JS::HandleValue) -> Result<f64, () > Err(()) > } > } > > #[inline] > unsafe fn convert_from_int32<T: Default + Copy>( > cx: *mut JSContext, > v: JS::HandleValue, >- conv_fn: unsafe extern "C" fn(*mut JSContext, JS::HandleValue, *mut T) -> bool) >- -> Result<T, ()> { >- >+ conv_fn: unsafe extern "C" fn(*mut JSContext, JS::HandleValue, *mut T) -> bool, >+) -> Result<T, ()> { > let val = *v.ptr; > if val.is_int32() { > let intval: i64 = val.to_int32() as i64; > // TODO: do something better here that works on big endian > let intval = *(&intval as *const i64 as *const T); > return Ok(intval); > } > >@@ -894,34 +917,39 @@ pub unsafe fn ToString(cx: *mut JSContext, v: JS::HandleValue) -> *mut JSString > let val = *v.ptr; > if val.is_string() { > return val.to_string(); > } > > js::ToStringSlow(cx, v) > } > >-pub unsafe extern fn report_warning(_cx: *mut JSContext, report: *mut JSErrorReport) { >+pub unsafe extern "C" fn report_warning(_cx: *mut JSContext, report: *mut JSErrorReport) { > fn latin1_to_string(bytes: &[u8]) -> String { >- bytes.iter().map(|c| char::from_u32(*c as u32).unwrap()).collect() >+ bytes >+ .iter() >+ .map(|c| char::from_u32(*c as u32).unwrap()) >+ .collect() > } > > let fnptr = (*report)._base.filename; > let fname = if !fnptr.is_null() { > let c_str = ffi::CStr::from_ptr(fnptr); > latin1_to_string(c_str.to_bytes()) > } else { > "none".to_string() > }; > > let lineno = (*report)._base.lineno; > let column = (*report)._base.column; > > let msg_ptr = (*report)._base.message_.data_ as *const u16; >- let msg_len = (0usize..).find(|&i| *msg_ptr.offset(i as isize) == 0).unwrap(); >+ let msg_len = (0usize..) >+ .find(|&i| *msg_ptr.offset(i as isize) == 0) >+ .unwrap(); > let msg_slice = slice::from_raw_parts(msg_ptr, msg_len); > let msg = String::from_utf16_lossy(msg_slice); > > warn!("Warning at {}:{}:{}: {}\n", fname, lineno, column, msg); > } > > impl JSNativeWrapper { > fn is_zeroed(&self) -> bool { >@@ -941,19 +969,17 @@ impl IdVector { > > pub fn get(&self) -> *mut JS::AutoIdVector { > self.0 > } > } > > impl Drop for IdVector { > fn drop(&mut self) { >- unsafe { >- DestroyAutoIdVector(self.0) >- } >+ unsafe { DestroyAutoIdVector(self.0) } > } > } > > impl Deref for IdVector { > type Target = [jsid]; > > fn deref(&self) -> &[jsid] { > unsafe { >@@ -974,25 +1000,36 @@ impl Deref for IdVector { > /// # Panics > /// > /// Panics if the last entry of `methods` does not contain zeroed memory. > /// > /// # Safety > /// > /// - `cx` must be valid. > /// - This function calls into unaudited C++ code. >-pub unsafe fn define_methods(cx: *mut JSContext, obj: JS::HandleObject, >- methods: &'static [JSFunctionSpec]) >- -> Result<(), ()> { >+pub unsafe fn define_methods( >+ cx: *mut JSContext, >+ obj: JS::HandleObject, >+ methods: &'static [JSFunctionSpec], >+) -> Result<(), ()> { > assert!({ > match methods.last() { >- Some(&JSFunctionSpec { name, call, nargs, flags, selfHostedName }) => { >- name.is_null() && call.is_zeroed() && nargs == 0 && flags == 0 && >- selfHostedName.is_null() >- }, >+ Some(&JSFunctionSpec { >+ name, >+ call, >+ nargs, >+ flags, >+ selfHostedName, >+ }) => { >+ name.is_null() >+ && call.is_zeroed() >+ && nargs == 0 >+ && flags == 0 >+ && selfHostedName.is_null() >+ } > None => false, > } > }); > > JS_DefineFunctions(cx, obj, methods.as_ptr()).to_result() > } > > /// Defines attributes on `obj`. The last entry of `properties` must contain >@@ -1005,24 +1042,28 @@ pub unsafe fn define_methods(cx: *mut JSContext, obj: JS::HandleObject, > /// # Panics > /// > /// Panics if the last entry of `properties` does not contain zeroed memory. > /// > /// # Safety > /// > /// - `cx` must be valid. > /// - This function calls into unaudited C++ code. >-pub unsafe fn define_properties(cx: *mut JSContext, obj: JS::HandleObject, >- properties: &'static [JSPropertySpec]) >- -> Result<(), ()> { >+pub unsafe fn define_properties( >+ cx: *mut JSContext, >+ obj: JS::HandleObject, >+ properties: &'static [JSPropertySpec], >+) -> Result<(), ()> { > assert!(!properties.is_empty()); > assert!({ > let spec = properties.last().unwrap(); >- let slice = slice::from_raw_parts(spec as *const _ as *const u8, >- mem::size_of::<JSPropertySpec>()); >+ let slice = slice::from_raw_parts( >+ spec as *const _ as *const u8, >+ mem::size_of::<JSPropertySpec>(), >+ ); > slice.iter().all(|byte| *byte == 0) > }); > > JS_DefineProperties(cx, obj, properties.as_ptr()).to_result() > } > > static SIMPLE_GLOBAL_CLASS_OPS: JSClassOps = JSClassOps { > addProperty: None, >@@ -1036,19 +1077,21 @@ static SIMPLE_GLOBAL_CLASS_OPS: JSClassOps = JSClassOps { > hasInstance: None, > construct: None, > trace: Some(JS_GlobalObjectTraceHook), > }; > > /// This is a simple `JSClass` for global objects, primarily intended for tests. > pub static SIMPLE_GLOBAL_CLASS: JSClass = JSClass { > name: b"Global\0" as *const u8 as *const _, >- flags: (JSCLASS_IS_GLOBAL | ((JSCLASS_GLOBAL_SLOT_COUNT & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT)) as u32, >+ flags: (JSCLASS_IS_GLOBAL >+ | ((JSCLASS_GLOBAL_SLOT_COUNT & JSCLASS_RESERVED_SLOTS_MASK) >+ << JSCLASS_RESERVED_SLOTS_SHIFT)) as u32, > cOps: &SIMPLE_GLOBAL_CLASS_OPS as *const JSClassOps, >- reserved: [0 as *mut _; 3] >+ reserved: [0 as *mut _; 3], > }; > > #[inline] > unsafe fn get_object_group(obj: *mut JSObject) -> *mut js::shadow::ObjectGroup { > assert!(!obj.is_null()); > let obj = obj as *mut js::shadow::Object; > (*obj).group > } >@@ -1102,19 +1145,17 @@ pub unsafe fn maybe_wrap_object_value(cx: *mut JSContext, rval: JS::MutableHandl > // not here, but JSAPI no longer exposes a way to get a JSContext's > // compartment, and additionally JSContext is under a bunch of churn in > // JSAPI in general right now. > > assert!(JS_WrapValue(cx, rval)); > } > > #[inline] >-pub unsafe fn maybe_wrap_object_or_null_value( >- cx: *mut JSContext, >- rval: JS::MutableHandleValue) { >+pub unsafe fn maybe_wrap_object_or_null_value(cx: *mut JSContext, rval: JS::MutableHandleValue) { > assert!(rval.is_object_or_null()); > if !rval.is_null() { > maybe_wrap_object_value(cx, rval); > } > } > > #[inline] > pub unsafe fn maybe_wrap_value(cx: *mut JSContext, rval: JS::MutableHandleValue) { >@@ -1122,36 +1163,40 @@ pub unsafe fn maybe_wrap_value(cx: *mut JSContext, rval: JS::MutableHandleValue) > assert!(JS_WrapValue(cx, rval)); > } else if rval.is_object() { > maybe_wrap_object_value(cx, rval); > } > } > > /// Equivalents of the JS_FN* macros. > impl JSFunctionSpec { >- pub fn js_fs(name: *const ::std::os::raw::c_char, >- func: JSNative, >- nargs: u16, >- flags: u16) -> JSFunctionSpec { >+ pub fn js_fs( >+ name: *const ::std::os::raw::c_char, >+ func: JSNative, >+ nargs: u16, >+ flags: u16, >+ ) -> JSFunctionSpec { > JSFunctionSpec { > name: name, > call: JSNativeWrapper { > op: func, > info: ptr::null(), > }, > nargs: nargs, > flags: flags, > selfHostedName: 0 as *const _, > } > } > >- pub fn js_fn(name: *const ::std::os::raw::c_char, >- func: JSNative, >- nargs: u16, >- flags: u16) -> JSFunctionSpec { >+ pub fn js_fn( >+ name: *const ::std::os::raw::c_char, >+ func: JSNative, >+ nargs: u16, >+ flags: u16, >+ ) -> JSFunctionSpec { > JSFunctionSpec { > name: name, > call: JSNativeWrapper { > op: func, > info: ptr::null(), > }, > nargs: nargs, > flags: flags, >@@ -1168,18 +1213,21 @@ impl JSFunctionSpec { > nargs: 0, > flags: 0, > selfHostedName: 0 as *const _, > }; > } > > /// Equivalents of the JS_PS* macros. > impl JSPropertySpec { >- pub fn getter(name: *const ::std::os::raw::c_char, flags: u8, func: JSNative) >- -> JSPropertySpec { >+ pub fn getter( >+ name: *const ::std::os::raw::c_char, >+ flags: u8, >+ func: JSNative, >+ ) -> JSPropertySpec { > debug_assert_eq!(flags & !(JSPROP_ENUMERATE | JSPROP_PERMANENT), 0); > JSPropertySpec { > name: name, > flags: flags, > __bindgen_anon_1: JSPropertySpec__bindgen_ty_1 { > accessors: JSPropertySpec__bindgen_ty_1__bindgen_ty_1 { > getter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { > native: JSNativeWrapper { >@@ -1187,27 +1235,28 @@ impl JSPropertySpec { > info: ptr::null(), > }, > }, > setter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { > native: JSNativeWrapper { > op: None, > info: ptr::null(), > }, >- } >- } >- } >+ }, >+ }, >+ }, > } > } > >- pub fn getter_setter(name: *const ::std::os::raw::c_char, >- flags: u8, >- g_f: JSNative, >- s_f: JSNative) >- -> JSPropertySpec { >+ pub fn getter_setter( >+ name: *const ::std::os::raw::c_char, >+ flags: u8, >+ g_f: JSNative, >+ s_f: JSNative, >+ ) -> JSPropertySpec { > debug_assert_eq!(flags & !(JSPROP_ENUMERATE | JSPROP_PERMANENT), 0); > JSPropertySpec { > name: name, > flags: flags, > __bindgen_anon_1: JSPropertySpec__bindgen_ty_1 { > accessors: JSPropertySpec__bindgen_ty_1__bindgen_ty_1 { > getter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { > native: JSNativeWrapper { >@@ -1215,35 +1264,35 @@ impl JSPropertySpec { > info: ptr::null(), > }, > }, > setter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { > native: JSNativeWrapper { > op: s_f, > info: ptr::null(), > }, >- } >- } >- } >+ }, >+ }, >+ }, > } > } > > pub const NULL: JSPropertySpec = JSPropertySpec { > name: 0 as *const _, > flags: 0, >- __bindgen_anon_1: JSPropertySpec__bindgen_ty_1{ >+ __bindgen_anon_1: JSPropertySpec__bindgen_ty_1 { > accessors: JSPropertySpec__bindgen_ty_1__bindgen_ty_1 { > getter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_1 { > native: JSNativeWrapper { > op: None, > info: 0 as *const _, > }, > }, > setter: JSPropertySpec__bindgen_ty_1__bindgen_ty_1__bindgen_ty_2 { > native: JSNativeWrapper { > op: None, > info: 0 as *const _, > }, >- } >- } >- } >+ }, >+ }, >+ }, > }; > } >diff --git a/js/rust/src/sc.rs b/js/rust/src/sc.rs >index a304a510e4c5..a847702f1f0d 100644 >--- a/js/rust/src/sc.rs >+++ b/js/rust/src/sc.rs >@@ -15,82 +15,71 @@ pub struct StructuredCloneBuffer { > } > > impl StructuredCloneBuffer { > /// Construct a new `StructuredCloneBuffer`. > /// > /// # Panics > /// > /// Panics if the underlying JSAPI calls fail. >- pub fn new(scope: jsapi::JS::StructuredCloneScope, >- callbacks: &jsapi::JSStructuredCloneCallbacks) >- -> StructuredCloneBuffer { >- let raw = unsafe { >- glue::NewJSAutoStructuredCloneBuffer(scope, callbacks) >- }; >+ pub fn new( >+ scope: jsapi::JS::StructuredCloneScope, >+ callbacks: &jsapi::JSStructuredCloneCallbacks, >+ ) -> StructuredCloneBuffer { >+ let raw = unsafe { glue::NewJSAutoStructuredCloneBuffer(scope, callbacks) }; > assert!(!raw.is_null()); >- StructuredCloneBuffer { >- raw: raw, >- } >+ StructuredCloneBuffer { raw: raw } > } > > /// Get the raw `*mut JSStructuredCloneData` owned by this buffer. > pub fn data(&self) -> *mut jsapi::JSStructuredCloneData { >- unsafe { >- &mut (*self.raw).data_ >- } >+ unsafe { &mut (*self.raw).data_ } > } > > /// Copy this buffer's data into a vec. > pub fn copy_to_vec(&self) -> Vec<u8> { >- let len = unsafe { >- glue::GetLengthOfJSStructuredCloneData(self.data()) >- }; >+ let len = unsafe { glue::GetLengthOfJSStructuredCloneData(self.data()) }; > let mut vec = Vec::with_capacity(len); > unsafe { > glue::CopyJSStructuredCloneData(self.data(), vec.as_mut_ptr()); > } > vec > } > > /// Read a JS value out of this buffer. >- pub fn read(&mut self, >- vp: jsapi::JS::MutableHandleValue, >- callbacks: &jsapi::JSStructuredCloneCallbacks) >- -> Result<(), ()> { >- if unsafe { >- (*self.raw).read(Runtime::get(), vp, callbacks, ptr::null_mut()) >- } { >+ pub fn read( >+ &mut self, >+ vp: jsapi::JS::MutableHandleValue, >+ callbacks: &jsapi::JSStructuredCloneCallbacks, >+ ) -> Result<(), ()> { >+ if unsafe { (*self.raw).read(Runtime::get(), vp, callbacks, ptr::null_mut()) } { > Ok(()) > } else { > Err(()) > } > } > > /// Write a JS value into this buffer. >- pub fn write(&mut self, >- v: jsapi::JS::HandleValue, >- callbacks: &jsapi::JSStructuredCloneCallbacks) >- -> Result<(), ()> { >- if unsafe { >- (*self.raw).write(Runtime::get(), v, callbacks, ptr::null_mut()) >- } { >+ pub fn write( >+ &mut self, >+ v: jsapi::JS::HandleValue, >+ callbacks: &jsapi::JSStructuredCloneCallbacks, >+ ) -> Result<(), ()> { >+ if unsafe { (*self.raw).write(Runtime::get(), v, callbacks, ptr::null_mut()) } { > Ok(()) > } else { > Err(()) > } > } > > /// Copy the given slice into this buffer. > pub fn write_bytes(&mut self, bytes: &[u8]) -> Result<(), ()> { > let len = bytes.len(); > let src = bytes.as_ptr(); >- if unsafe { >- glue::WriteBytesToJSStructuredCloneData(src, len, self.data()) >- } { >+ if unsafe { glue::WriteBytesToJSStructuredCloneData(src, len, self.data()) } { > Ok(()) > } else { > Err(()) > } > } > } > > impl Drop for StructuredCloneBuffer { >diff --git a/js/rust/src/typedarray.rs b/js/rust/src/typedarray.rs >index f44721235a6b..f9fbf8ac9737 100644 >--- a/js/rust/src/typedarray.rs >+++ b/js/rust/src/typedarray.rs >@@ -10,19 +10,19 @@ use glue::GetFloat32ArrayLengthAndData; > use glue::GetFloat64ArrayLengthAndData; > use glue::GetInt16ArrayLengthAndData; > use glue::GetInt32ArrayLengthAndData; > use glue::GetInt8ArrayLengthAndData; > use glue::GetUint16ArrayLengthAndData; > use glue::GetUint32ArrayLengthAndData; > use glue::GetUint8ArrayLengthAndData; > use glue::GetUint8ClampedArrayLengthAndData; >-use jsapi::*; > use jsapi::js::*; > use jsapi::JS::*; >+use jsapi::*; > use rust::RootedGuard; > use std::ptr; > use std::slice; > > pub enum CreateWith<'a, T: 'a> { > Length(u32), > Slice(&'a [T]), > } >@@ -32,20 +32,21 @@ pub struct TypedArray<'a, T: 'a + TypedArrayElement> { > object: RootedGuard<'a, *mut JSObject>, > computed: Option<(*mut T::Element, u32)>, > } > > impl<'a, T: TypedArrayElement> TypedArray<'a, T> { > /// Create a typed array representation that wraps an existing JS reflector. > /// This operation will fail if attempted on a JS object that does not match > /// the expected typed array details. >- pub fn from(cx: *mut JSContext, >- root: &'a mut Rooted<*mut JSObject>, >- object: *mut JSObject) >- -> Result<Self, ()> { >+ pub fn from( >+ cx: *mut JSContext, >+ root: &'a mut Rooted<*mut JSObject>, >+ object: *mut JSObject, >+ ) -> Result<Self, ()> { > if object.is_null() { > return Err(()); > } > unsafe { > let mut guard = RootedGuard::new(cx, root, object); > let unwrapped = T::unwrap_array(*guard); > if unwrapped.is_null() { > return Err(()); >@@ -89,20 +90,21 @@ impl<'a, T: TypedArrayElement> TypedArray<'a, T> { > let (pointer, length) = self.data(); > slice::from_raw_parts_mut(pointer, length as usize) > } > } > > impl<'a, T: TypedArrayElementCreator + TypedArrayElement> TypedArray<'a, T> { > /// Create a new JS typed array, optionally providing initial data that will > /// be copied into the newly-allocated buffer. Returns the new JS reflector. >- pub unsafe fn create(cx: *mut JSContext, >- with: CreateWith<T::Element>, >- result: MutableHandleObject) >- -> Result<(), ()> { >+ pub unsafe fn create( >+ cx: *mut JSContext, >+ with: CreateWith<T::Element>, >+ result: MutableHandleObject, >+ ) -> Result<(), ()> { > let length = match with { > CreateWith::Length(len) => len, > CreateWith::Slice(slice) => slice.len() as u32, > }; > > result.set(T::create_new(cx, length)); > if result.get().is_null() { > return Err(()); >@@ -145,17 +147,17 @@ pub trait TypedArrayElementCreator: TypedArrayElement { > /// Get the data. > unsafe fn get_data(obj: *mut JSObject) -> *mut Self::Element; > } > > macro_rules! typed_array_element { > ($t: ident, > $element: ty, > $unwrap: ident, >- $length_and_data: ident) => ( >+ $length_and_data: ident) => { > /// A kind of typed array. > pub struct $t; > > impl TypedArrayElement for $t { > type Element = $element; > unsafe fn unwrap_array(obj: *mut JSObject) -> *mut JSObject { > $unwrap(obj) > } >@@ -164,105 +166,127 @@ macro_rules! typed_array_element { > let mut len = 0; > let mut shared = false; > let mut data = ptr::null_mut(); > $length_and_data(obj, &mut len, &mut shared, &mut data); > assert!(!shared); > (data, len) > } > } >- ); >+ }; > > ($t: ident, > $element: ty, > $unwrap: ident, > $length_and_data: ident, > $create_new: ident, >- $get_data: ident) => ( >+ $get_data: ident) => { > typed_array_element!($t, $element, $unwrap, $length_and_data); > > impl TypedArrayElementCreator for $t { > unsafe fn create_new(cx: *mut JSContext, length: u32) -> *mut JSObject { > $create_new(cx, length) > } > > unsafe fn get_data(obj: *mut JSObject) -> *mut Self::Element { > let mut shared = false; > let data = $get_data(obj, &mut shared, ptr::null_mut()); > assert!(!shared); > data > } > } >- ); >+ }; > } > >-typed_array_element!(Uint8, >- u8, >- UnwrapUint8Array, >- GetUint8ArrayLengthAndData, >- JS_NewUint8Array, >- JS_GetUint8ArrayData); >-typed_array_element!(Uint16, >- u16, >- UnwrapUint16Array, >- GetUint16ArrayLengthAndData, >- JS_NewUint16Array, >- JS_GetUint16ArrayData); >-typed_array_element!(Uint32, >- u32, >- UnwrapUint32Array, >- GetUint32ArrayLengthAndData, >- JS_NewUint32Array, >- JS_GetUint32ArrayData); >-typed_array_element!(Int8, >- i8, >- UnwrapInt8Array, >- GetInt8ArrayLengthAndData, >- JS_NewInt8Array, >- JS_GetInt8ArrayData); >-typed_array_element!(Int16, >- i16, >- UnwrapInt16Array, >- GetInt16ArrayLengthAndData, >- JS_NewInt16Array, >- JS_GetInt16ArrayData); >-typed_array_element!(Int32, >- i32, >- UnwrapInt32Array, >- GetInt32ArrayLengthAndData, >- JS_NewInt32Array, >- JS_GetInt32ArrayData); >-typed_array_element!(Float32, >- f32, >- UnwrapFloat32Array, >- GetFloat32ArrayLengthAndData, >- JS_NewFloat32Array, >- JS_GetFloat32ArrayData); >-typed_array_element!(Float64, >- f64, >- UnwrapFloat64Array, >- GetFloat64ArrayLengthAndData, >- JS_NewFloat64Array, >- JS_GetFloat64ArrayData); >-typed_array_element!(ClampedU8, >- u8, >- UnwrapUint8ClampedArray, >- GetUint8ClampedArrayLengthAndData, >- JS_NewUint8ClampedArray, >- JS_GetUint8ClampedArrayData); >-typed_array_element!(ArrayBufferU8, >- u8, >- UnwrapArrayBuffer, >- GetArrayBufferLengthAndData, >- JS_NewArrayBuffer, >- JS_GetArrayBufferData); >-typed_array_element!(ArrayBufferViewU8, >- u8, >- UnwrapArrayBufferView, >- GetArrayBufferViewLengthAndData); >+typed_array_element!( >+ Uint8, >+ u8, >+ UnwrapUint8Array, >+ GetUint8ArrayLengthAndData, >+ JS_NewUint8Array, >+ JS_GetUint8ArrayData >+); >+typed_array_element!( >+ Uint16, >+ u16, >+ UnwrapUint16Array, >+ GetUint16ArrayLengthAndData, >+ JS_NewUint16Array, >+ JS_GetUint16ArrayData >+); >+typed_array_element!( >+ Uint32, >+ u32, >+ UnwrapUint32Array, >+ GetUint32ArrayLengthAndData, >+ JS_NewUint32Array, >+ JS_GetUint32ArrayData >+); >+typed_array_element!( >+ Int8, >+ i8, >+ UnwrapInt8Array, >+ GetInt8ArrayLengthAndData, >+ JS_NewInt8Array, >+ JS_GetInt8ArrayData >+); >+typed_array_element!( >+ Int16, >+ i16, >+ UnwrapInt16Array, >+ GetInt16ArrayLengthAndData, >+ JS_NewInt16Array, >+ JS_GetInt16ArrayData >+); >+typed_array_element!( >+ Int32, >+ i32, >+ UnwrapInt32Array, >+ GetInt32ArrayLengthAndData, >+ JS_NewInt32Array, >+ JS_GetInt32ArrayData >+); >+typed_array_element!( >+ Float32, >+ f32, >+ UnwrapFloat32Array, >+ GetFloat32ArrayLengthAndData, >+ JS_NewFloat32Array, >+ JS_GetFloat32ArrayData >+); >+typed_array_element!( >+ Float64, >+ f64, >+ UnwrapFloat64Array, >+ GetFloat64ArrayLengthAndData, >+ JS_NewFloat64Array, >+ JS_GetFloat64ArrayData >+); >+typed_array_element!( >+ ClampedU8, >+ u8, >+ UnwrapUint8ClampedArray, >+ GetUint8ClampedArrayLengthAndData, >+ JS_NewUint8ClampedArray, >+ JS_GetUint8ClampedArrayData >+); >+typed_array_element!( >+ ArrayBufferU8, >+ u8, >+ UnwrapArrayBuffer, >+ GetArrayBufferLengthAndData, >+ JS_NewArrayBuffer, >+ JS_GetArrayBufferData >+); >+typed_array_element!( >+ ArrayBufferViewU8, >+ u8, >+ UnwrapArrayBufferView, >+ GetArrayBufferViewLengthAndData >+); > > /// The Uint8ClampedArray type. > pub type Uint8ClampedArray<'a> = TypedArray<'a, ClampedU8>; > /// The Uint8Array type. > pub type Uint8Array<'a> = TypedArray<'a, Uint8>; > /// The Int8Array type. > pub type Int8Array<'a> = TypedArray<'a, Int8>; > /// The Uint16Array type. >@@ -292,10 +316,10 @@ impl<'a> ArrayBufferView<'a> { > macro_rules! typedarray { > (in($cx:expr) let $name:ident : $ty:ident = $init:expr) => { > let mut __root = $crate::jsapi::JS::Rooted::new_unrooted(); > let $name = $crate::typedarray::$ty::from($cx, &mut __root, $init); > }; > (in($cx:expr) let mut $name:ident : $ty:ident = $init:expr) => { > let mut __root = $crate::jsapi::JS::Rooted::new_unrooted(); > let mut $name = $crate::typedarray::$ty::from($cx, &mut __root, $init); >- } >+ }; > } >diff --git a/js/rust/tests/bigint.rs b/js/rust/tests/bigint.rs >index 921931027fe4..03dc5287ed5d 100644 >--- a/js/rust/tests/bigint.rs >+++ b/js/rust/tests/bigint.rs >@@ -1,13 +1,13 @@ > #[macro_use] > extern crate js; > >-use js::jsapi::root::JS::CompartmentOptions; > use js::jsapi::root::JS_NewGlobalObject; >+use js::jsapi::root::JS::CompartmentOptions; > use js::jsapi::root::JS::OnNewGlobalHookOption; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ptr; > > #[test] > fn is_bigint() { >@@ -17,18 +17,20 @@ fn is_bigint() { > unsafe { > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &CompartmentOptions::default()) > ); > > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "BigInt(0)", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script(global.handle(), "BigInt(0)", "test", 1, rval.handle_mut()) >+ .is_ok() >+ ); > assert!(rval.is_bigint()); > } > } > > #[test] > fn is_not_bigint() { > let rt = Runtime::new(false).unwrap(); > let cx = rt.cx(); >@@ -36,13 +38,20 @@ fn is_not_bigint() { > unsafe { > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &CompartmentOptions::default()) > ); > > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "'not a BigInt'", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script( >+ global.handle(), >+ "'not a BigInt'", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_ok() >+ ); > assert!(!rval.is_bigint()); > } > } >diff --git a/js/rust/tests/callback.rs b/js/rust/tests/callback.rs >index a8c9972ff6dd..fa3c62c45af3 100644 >--- a/js/rust/tests/callback.rs >+++ b/js/rust/tests/callback.rs >@@ -2,58 +2,73 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this file, > * You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #[macro_use] > extern crate js; > extern crate libc; > > use js::ac::AutoCompartment; >-use js::jsapi::root::JS::CallArgs; >-use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::JSContext; > use js::jsapi::root::JS_DefineFunction; > use js::jsapi::root::JS_EncodeStringToUTF8; > use js::jsapi::root::JS_NewGlobalObject; > use js::jsapi::root::JS_ReportErrorASCII; >+use js::jsapi::root::JS::CallArgs; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::JS::Value; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ffi::CStr; > use std::ptr; > use std::str; > > #[test] > fn callback() { > let runtime = Runtime::new(false).unwrap(); > let context = runtime.cx(); > let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; > let c_option = RealmOptions::default(); > > unsafe { >- let global = JS_NewGlobalObject(context, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), h_option, &c_option); >+ let global = JS_NewGlobalObject( >+ context, >+ &SIMPLE_GLOBAL_CLASS, >+ ptr::null_mut(), >+ h_option, >+ &c_option, >+ ); > rooted!(in(context) let global_root = global); > let global = global_root.handle(); > let _ac = AutoCompartment::with_obj(context, global.get()); >- let function = JS_DefineFunction(context, global, b"puts\0".as_ptr() as *const libc::c_char, >- Some(puts), 1, 0); >+ let function = JS_DefineFunction( >+ context, >+ global, >+ b"puts\0".as_ptr() as *const libc::c_char, >+ Some(puts), >+ 1, >+ 0, >+ ); > assert!(!function.is_null()); > let javascript = "puts('Test Iñtërnâtiônà lizætiøn â¬ââ¬ã( º _ ºã) ');"; > rooted!(in(context) let mut rval = UndefinedValue()); > let _ = runtime.evaluate_script(global, javascript, "test.js", 0, rval.handle_mut()); > } > } > > unsafe extern "C" fn puts(context: *mut JSContext, argc: u32, vp: *mut Value) -> bool { > let args = CallArgs::from_vp(vp, argc); > > if args._base.argc_ != 1 { >- JS_ReportErrorASCII(context, b"puts() requires exactly 1 argument\0".as_ptr() as *const libc::c_char); >+ JS_ReportErrorASCII( >+ context, >+ b"puts() requires exactly 1 argument\0".as_ptr() as *const libc::c_char, >+ ); > return false; > } > > let arg = args.get(0); > let js = js::rust::ToString(context, arg); > rooted!(in(context) let message_root = js); > let message = JS_EncodeStringToUTF8(context, message_root.handle()); > let message = CStr::from_ptr(message); >diff --git a/js/rust/tests/enumerate.rs b/js/rust/tests/enumerate.rs >index 3e7e02a99cc3..53c2d29a2a4d 100644 >--- a/js/rust/tests/enumerate.rs >+++ b/js/rust/tests/enumerate.rs >@@ -2,22 +2,22 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #[macro_use] > extern crate js; > > use js::glue::RUST_JSID_IS_STRING; > use js::glue::RUST_JSID_TO_STRING; >-use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::js::GetPropertyKeys; >-use js::jsapi::root::JSITER_OWNONLY; > use js::jsapi::root::JS_NewGlobalObject; > use js::jsapi::root::JS_StringEqualsAscii; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; >+use js::jsapi::root::JSITER_OWNONLY; > use js::jsval::UndefinedValue; > use js::rust::IdVector; > use js::rust::Runtime; > use js::rust::SIMPLE_GLOBAL_CLASS; > use std::ptr; > > #[test] > fn enumerate() { >@@ -27,30 +27,44 @@ fn enumerate() { > unsafe { > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &RealmOptions::default()) > ); > > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "({ 'a': 7 })", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script( >+ global.handle(), >+ "({ 'a': 7 })", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_ok() >+ ); > assert!(rval.is_object()); > > rooted!(in(cx) let object = rval.to_object()); > let ids = IdVector::new(cx); >- assert!(GetPropertyKeys(cx, object.handle(), JSITER_OWNONLY, ids.get())); >+ assert!(GetPropertyKeys( >+ cx, >+ object.handle(), >+ JSITER_OWNONLY, >+ ids.get() >+ )); > > assert_eq!(ids.len(), 1); > rooted!(in(cx) let id = ids[0]); > > assert!(RUST_JSID_IS_STRING(id.handle())); > rooted!(in(cx) let id = RUST_JSID_TO_STRING(id.handle())); > > let mut matches = false; >- assert!(JS_StringEqualsAscii(cx, >- id.get(), >- b"a\0" as *const _ as *const _, >- &mut matches)); >+ assert!(JS_StringEqualsAscii( >+ cx, >+ id.get(), >+ b"a\0" as *const _ as *const _, >+ &mut matches >+ )); > assert!(matches); > } > } >diff --git a/js/rust/tests/evaluate.rs b/js/rust/tests/evaluate.rs >index ae8de51beb0b..7bdad8415243 100644 >--- a/js/rust/tests/evaluate.rs >+++ b/js/rust/tests/evaluate.rs >@@ -1,32 +1,33 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #[macro_use] > extern crate js; > >-use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::JS_NewGlobalObject; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ptr; > > #[test] > fn evaluate() { > let rt = Runtime::new(false).unwrap(); > let cx = rt.cx(); > > unsafe { >- > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &RealmOptions::default()) > ); > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "1 + 1", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script(global.handle(), "1 + 1", "test", 1, rval.handle_mut()) >+ .is_ok() >+ ); > } > } >diff --git a/js/rust/tests/panic.rs b/js/rust/tests/panic.rs >index 616fdd7d733e..41d66cba7f78 100644 >--- a/js/rust/tests/panic.rs >+++ b/js/rust/tests/panic.rs >@@ -16,28 +16,35 @@ use std::str; > #[should_panic] > fn panic() { > let runtime = Runtime::new(false).unwrap(); > let context = runtime.cx(); > let h_option = JS::OnNewGlobalHookOption::FireOnNewGlobalHook; > let c_option = JS::RealmOptions::default(); > > unsafe { >- let global = JS_NewGlobalObject(context, &SIMPLE_GLOBAL_CLASS, >- ptr::null_mut(), h_option, &c_option); >+ let global = JS_NewGlobalObject( >+ context, >+ &SIMPLE_GLOBAL_CLASS, >+ ptr::null_mut(), >+ h_option, >+ &c_option, >+ ); > rooted!(in(context) let global_root = global); > let global = global_root.handle(); > let _ac = js::ac::AutoCompartment::with_obj(context, global.get()); >- let function = JS_DefineFunction(context, global, >- b"test\0".as_ptr() as *const _, >- Some(test), 0, 0); >+ let function = JS_DefineFunction( >+ context, >+ global, >+ b"test\0".as_ptr() as *const _, >+ Some(test), >+ 0, >+ 0, >+ ); > assert!(!function.is_null()); > rooted!(in(context) let mut rval = UndefinedValue()); >- let _ = runtime.evaluate_script(global, "test();", "test.js", 0, >- rval.handle_mut()); >+ let _ = runtime.evaluate_script(global, "test();", "test.js", 0, rval.handle_mut()); > } > } > > unsafe extern "C" fn test(_cx: *mut JSContext, _argc: u32, _vp: *mut JS::Value) -> bool { >- wrap_panic(|| { >- panic!() >- }, false) >+ wrap_panic(|| panic!(), false) > } >diff --git a/js/rust/tests/rooting.rs b/js/rust/tests/rooting.rs >index 2a4f147fd471..8e352ca0eff2 100644 >--- a/js/rust/tests/rooting.rs >+++ b/js/rust/tests/rooting.rs >@@ -6,17 +6,17 @@ > > #[macro_use] > extern crate js; > #[macro_use] > extern crate lazy_static; > extern crate libc; > > use js::jsapi::*; >-use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS, define_methods}; >+use js::rust::{define_methods, Runtime, SIMPLE_GLOBAL_CLASS}; > use std::ptr; > > #[test] > fn rooting() { > unsafe { > let runtime = Runtime::new(false).unwrap(); > JS_SetGCZeal(runtime.cx(), 2, 1); > >@@ -41,43 +41,55 @@ fn rooting() { > unsafe extern "C" fn generic_method(_: *mut JSContext, _: u32, _: *mut JS::Value) -> bool { > true > } > > lazy_static! { > static ref METHODS: [JSFunctionSpec; 4] = [ > JSFunctionSpec { > name: b"addEventListener\0" as *const u8 as *const libc::c_char, >- call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, >+ call: JSNativeWrapper { >+ op: Some(generic_method), >+ info: ptr::null() >+ }, > nargs: 2, > flags: JSPROP_ENUMERATE as u16, > selfHostedName: 0 as *const libc::c_char > }, > JSFunctionSpec { > name: b"removeEventListener\0" as *const u8 as *const libc::c_char, >- call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, >+ call: JSNativeWrapper { >+ op: Some(generic_method), >+ info: ptr::null() >+ }, > nargs: 2, > flags: JSPROP_ENUMERATE as u16, > selfHostedName: 0 as *const libc::c_char > }, > JSFunctionSpec { > name: b"dispatchEvent\0" as *const u8 as *const libc::c_char, >- call: JSNativeWrapper { op: Some(generic_method), info: ptr::null() }, >+ call: JSNativeWrapper { >+ op: Some(generic_method), >+ info: ptr::null() >+ }, > nargs: 1, > flags: JSPROP_ENUMERATE as u16, > selfHostedName: 0 as *const libc::c_char > }, > JSFunctionSpec { > name: ptr::null(), >- call: JSNativeWrapper { op: None, info: ptr::null() }, >+ call: JSNativeWrapper { >+ op: None, >+ info: ptr::null() >+ }, > nargs: 0, > flags: 0, > selfHostedName: ptr::null() > } > ]; > } > > static CLASS: JSClass = JSClass { > name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, > flags: 0, > cOps: 0 as *const _, >- reserved: [0 as *mut _; 3] >+ reserved: [0 as *mut _; 3], > }; >diff --git a/js/rust/tests/runtime.rs b/js/rust/tests/runtime.rs >index 86dd864a2baf..b31d1cebb5cd 100644 >--- a/js/rust/tests/runtime.rs >+++ b/js/rust/tests/runtime.rs >@@ -26,17 +26,17 @@ fn runtime() { > &c_option)); > let _ac = js::ac::AutoCompartment::with_obj(cx, global.get()); > rooted!(in(cx) let _object = JS_NewObject(cx, &CLASS as *const _)); > } > > assert!(Runtime::new(false).is_err()); > } > >-unsafe extern fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) { >+unsafe extern "C" fn finalize(_fop: *mut JSFreeOp, _object: *mut JSObject) { > assert!(!Runtime::get().is_null()); > } > > static CLASS_OPS: JSClassOps = JSClassOps { > addProperty: None, > delProperty: None, > enumerate: None, > newEnumerate: None, >@@ -48,10 +48,10 @@ static CLASS_OPS: JSClassOps = JSClassOps { > construct: None, > trace: None, > }; > > static CLASS: JSClass = JSClass { > name: b"EventTargetPrototype\0" as *const u8 as *const libc::c_char, > flags: 0 | JSCLASS_FOREGROUND_FINALIZE, > cOps: &CLASS_OPS as *const JSClassOps, >- reserved: [0 as *mut _; 3] >+ reserved: [0 as *mut _; 3], > }; >diff --git a/js/rust/tests/stack_limit.rs b/js/rust/tests/stack_limit.rs >index e0a0bf1d0f9f..82c2510086d4 100644 >--- a/js/rust/tests/stack_limit.rs >+++ b/js/rust/tests/stack_limit.rs >@@ -1,32 +1,44 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #[macro_use] > extern crate js; > >-use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::JS_NewGlobalObject; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ptr; > > #[test] > fn stack_limit() { > let rt = Runtime::new(false).unwrap(); > let cx = rt.cx(); > > unsafe { > let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; > let c_option = RealmOptions::default(); >- let global = JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, >- ptr::null_mut(), h_option, &c_option); >+ let global = JS_NewGlobalObject( >+ cx, >+ &SIMPLE_GLOBAL_CLASS, >+ ptr::null_mut(), >+ h_option, >+ &c_option, >+ ); > rooted!(in(cx) let global_root = global); > let global = global_root.handle(); > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global, "function f() { f.apply() } f()", >- "test", 1, rval.handle_mut()).is_err()); >+ assert!( >+ rt.evaluate_script( >+ global, >+ "function f() { f.apply() } f()", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_err() >+ ); > } > } >diff --git a/js/rust/tests/typedarray.rs b/js/rust/tests/typedarray.rs >index d99eab731861..b43bb68d32f1 100644 >--- a/js/rust/tests/typedarray.rs >+++ b/js/rust/tests/typedarray.rs >@@ -22,28 +22,38 @@ fn typedarray() { > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > JS::OnNewGlobalHookOption::FireOnNewGlobalHook, > &JS::RealmOptions::default()) > ); > > let _ac = js::ac::AutoCompartment::with_obj(cx, global.get()); > > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "new Uint8Array([0, 2, 4])", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script( >+ global.handle(), >+ "new Uint8Array([0, 2, 4])", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_ok() >+ ); > assert!(rval.is_object()); > > typedarray!(in(cx) let array: Uint8Array = rval.to_object()); > assert_eq!(array.unwrap().as_slice(), &[0, 2, 4][..]); > > typedarray!(in(cx) let array: Uint16Array = rval.to_object()); > assert!(array.is_err()); > > typedarray!(in(cx) let view: ArrayBufferView = rval.to_object()); >- assert_eq!(view.unwrap().get_array_type(), js::jsapi::js::Scalar::Type::Uint8); >+ assert_eq!( >+ view.unwrap().get_array_type(), >+ js::jsapi::js::Scalar::Type::Uint8 >+ ); > > rooted!(in(cx) let mut rval = ptr::null_mut()); > assert!(Uint32Array::create(cx, CreateWith::Slice(&[1, 3, 5]), rval.handle_mut()).is_ok()); > > typedarray!(in(cx) let array: Uint32Array = rval.get()); > assert_eq!(array.unwrap().as_slice(), &[1, 3, 5][..]); > > typedarray!(in(cx) let mut array: Uint32Array = rval.get()); >@@ -60,17 +70,20 @@ fn typedarray() { > typedarray!(in(cx) let array: Uint32Array = rval.get()); > assert_eq!(array.unwrap().as_slice(), &[0, 0, 0, 0, 0]); > > typedarray!(in(cx) let mut array: Uint32Array = rval.get()); > array.as_mut().unwrap().update(&[0, 1, 2, 3]); > assert_eq!(array.unwrap().as_slice(), &[0, 1, 2, 3, 0]); > > typedarray!(in(cx) let view: ArrayBufferView = rval.get()); >- assert_eq!(view.unwrap().get_array_type(), js::jsapi::js::Scalar::Type::Uint32); >+ assert_eq!( >+ view.unwrap().get_array_type(), >+ js::jsapi::js::Scalar::Type::Uint32 >+ ); > } > } > > #[test] > #[should_panic] > fn typedarray_update_panic() { > let rt = Runtime_::new(false).unwrap(); > let cx = rt.cx(); >diff --git a/js/rust/tests/value.rs b/js/rust/tests/value.rs >index a844a52118c9..299e0ed83ce3 100644 >--- a/js/rust/tests/value.rs >+++ b/js/rust/tests/value.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #[macro_use] > extern crate js; > >-use js::jsapi::root::JS::RealmOptions; > use js::jsapi::root::JS_NewGlobalObject; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ptr; > > #[test] > fn is_symbol() { > let rt = Runtime::new(false).unwrap(); >@@ -20,31 +20,45 @@ fn is_symbol() { > > unsafe { > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &RealmOptions::default()) > ); > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "Symbol('test')", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script( >+ global.handle(), >+ "Symbol('test')", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_ok() >+ ); > assert!(rval.is_symbol()); > } > } > > #[test] > fn is_not_symbol() { > let rt = Runtime::new(false).unwrap(); > let cx = rt.cx(); > > unsafe { > rooted!(in(cx) let global = > JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, ptr::null_mut(), > OnNewGlobalHookOption::FireOnNewGlobalHook, > &RealmOptions::default()) > ); > rooted!(in(cx) let mut rval = UndefinedValue()); >- assert!(rt.evaluate_script(global.handle(), "'not a symbol'", >- "test", 1, rval.handle_mut()).is_ok()); >+ assert!( >+ rt.evaluate_script( >+ global.handle(), >+ "'not a symbol'", >+ "test", >+ 1, >+ rval.handle_mut() >+ ).is_ok() >+ ); > assert!(!rval.is_symbol()); > } > } >diff --git a/js/rust/tests/vec_conversion.rs b/js/rust/tests/vec_conversion.rs >index fca5d06b60e1..2c9db99fe08c 100644 >--- a/js/rust/tests/vec_conversion.rs >+++ b/js/rust/tests/vec_conversion.rs >@@ -5,45 +5,47 @@ > #[macro_use] > extern crate js; > > use js::ac::AutoCompartment; > use js::conversions::ConversionBehavior; > use js::conversions::ConversionResult; > use js::conversions::FromJSValConvertible; > use js::conversions::ToJSValConvertible; >-use js::jsapi::root::JS::RealmOptions; >-use js::jsapi::root::JS::InitRealmStandardClasses; > use js::jsapi::root::JS_NewGlobalObject; >+use js::jsapi::root::JS::InitRealmStandardClasses; > use js::jsapi::root::JS::OnNewGlobalHookOption; >+use js::jsapi::root::JS::RealmOptions; > use js::jsval::UndefinedValue; > use js::rust::{Runtime, SIMPLE_GLOBAL_CLASS}; > > use std::ptr; > >-fn assert_is_array(cx: *mut js::jsapi::root::JSContext, >- val: js::jsapi::root::JS::HandleValue) { >+fn assert_is_array(cx: *mut js::jsapi::root::JSContext, val: js::jsapi::root::JS::HandleValue) { > let mut is_array = false; >- assert!(unsafe { >- js::jsapi::root::JS_IsArrayObject(cx, val, &mut is_array as *mut _) >- }); >+ assert!(unsafe { js::jsapi::root::JS_IsArrayObject(cx, val, &mut is_array as *mut _) }); > assert!(is_array); > } > > #[test] > fn vec_conversion() { > let rt = Runtime::new(false).unwrap(); > let cx = rt.cx(); > > let h_option = OnNewGlobalHookOption::FireOnNewGlobalHook; > let c_option = RealmOptions::default(); > > unsafe { >- let global = JS_NewGlobalObject(cx, &SIMPLE_GLOBAL_CLASS, >- ptr::null_mut(), h_option, &c_option); >+ let global = JS_NewGlobalObject( >+ cx, >+ &SIMPLE_GLOBAL_CLASS, >+ ptr::null_mut(), >+ h_option, >+ &c_option, >+ ); > rooted!(in(cx) let global_root = global); > let global = global_root.handle(); > > let _ac = AutoCompartment::with_obj(cx, global.get()); > assert!(InitRealmStandardClasses(cx)); > > rooted!(in(cx) let mut rval = UndefinedValue()); > >@@ -51,30 +53,29 @@ fn vec_conversion() { > orig_vec.to_jsval(cx, rval.handle_mut()); > assert_is_array(cx, rval.handle()); > let converted = Vec::<f32>::from_jsval(cx, rval.handle(), ()).unwrap(); > assert_eq!(&orig_vec, converted.get_success_value().unwrap()); > > let orig_vec: Vec<i32> = vec![1, 2, 3]; > orig_vec.to_jsval(cx, rval.handle_mut()); > assert_is_array(cx, rval.handle()); >- let converted = Vec::<i32>::from_jsval(cx, rval.handle(), >- ConversionBehavior::Default).unwrap(); >+ let converted = >+ Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default).unwrap(); > > assert_eq!(&orig_vec, converted.get_success_value().unwrap()); > >- rt.evaluate_script(global, "new Set([1, 2, 3])", >- "test", 1, rval.handle_mut()).unwrap(); >+ rt.evaluate_script(global, "new Set([1, 2, 3])", "test", 1, rval.handle_mut()) >+ .unwrap(); > let converted = >- Vec::<i32>::from_jsval(cx, rval.handle(), >- ConversionBehavior::Default).unwrap(); >+ Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default).unwrap(); > > assert_eq!(&orig_vec, converted.get_success_value().unwrap()); > >- rt.evaluate_script(global, "({})", "test", 1, rval.handle_mut()).unwrap(); >- let converted = Vec::<i32>::from_jsval(cx, rval.handle(), >- ConversionBehavior::Default); >+ rt.evaluate_script(global, "({})", "test", 1, rval.handle_mut()) >+ .unwrap(); >+ let converted = Vec::<i32>::from_jsval(cx, rval.handle(), ConversionBehavior::Default); > assert!(match converted { > Ok(ConversionResult::Failure(_)) => true, > _ => false, > }); > } > } >diff --git a/js/src/build.rs b/js/src/build.rs >index e42c1020d0b8..d4ca67837aea 100644 >--- a/js/src/build.rs >+++ b/js/src/build.rs >@@ -11,43 +11,53 @@ fn main() { > let out_dir = env::var("OUT_DIR").expect("Should have env var OUT_DIR"); > let target = env::var("TARGET").expect("Should have env var TARGET"); > > let js_src = env::var("CARGO_MANIFEST_DIR").expect("Should have env var CARGO_MANIFEST_DIR"); > > env::set_var("MAKEFLAGS", format!("-j{}", num_cpus::get())); > env::set_current_dir(&js_src).unwrap(); > >- let variant = format!("{}{}", >- if cfg!(feature = "bigint") { "bigint" } else { "plain" }, >- if cfg!(feature = "debugmozjs") { "debug" } else { "" }); >+ let variant = format!( >+ "{}{}", >+ if cfg!(feature = "bigint") { >+ "bigint" >+ } else { >+ "plain" >+ }, >+ if cfg!(feature = "debugmozjs") { >+ "debug" >+ } else { >+ "" >+ } >+ ); > > let python = env::var("PYTHON").unwrap_or("python2.7".into()); > let mut cmd = Command::new(&python); >- cmd.args(&["./devtools/automation/autospider.py", >- // Only build SpiderMonkey, don't run all the tests. >- "--build-only", >- // Disable Mozilla's jemalloc; Rust has its own jemalloc that we >- // can swap in instead and everything using a single malloc is >- // good. >- "--no-jemalloc", >- // Don't try to clobber the output directory. Without >- // this option, the build will fail because the directory >- // already exists but wasn't created by autospider. >- "--dep", >- "--objdir", &out_dir, >- &variant]) >- .env("SOURCE", &js_src) >- .env("PWD", &js_src) >- .stdout(Stdio::inherit()) >- .stderr(Stdio::inherit()); >+ cmd.args(&[ >+ "./devtools/automation/autospider.py", >+ // Only build SpiderMonkey, don't run all the tests. >+ "--build-only", >+ // Disable Mozilla's jemalloc; Rust has its own jemalloc that we >+ // can swap in instead and everything using a single malloc is >+ // good. >+ "--no-jemalloc", >+ // Don't try to clobber the output directory. Without >+ // this option, the build will fail because the directory >+ // already exists but wasn't created by autospider. >+ "--dep", >+ "--objdir", >+ &out_dir, >+ &variant, >+ ]).env("SOURCE", &js_src) >+ .env("PWD", &js_src) >+ .stdout(Stdio::inherit()) >+ .stderr(Stdio::inherit()); > println!("Running command: {:?}", cmd); >- let result = cmd >- .status() >- .expect("Should spawn autospider OK"); >+ let result = cmd.status().expect("Should spawn autospider OK"); > assert!(result.success(), "autospider should exit OK"); > > println!("cargo:rustc-link-search=native={}/js/src/build", out_dir); > println!("cargo:rustc-link-search=native={}/js/src", out_dir); > println!("cargo:rustc-link-lib=static=js_static"); > > println!("cargo:rustc-link-search=native={}/dist/bin", out_dir); > println!("cargo:rustc-link-lib=nspr4"); >diff --git a/js/src/frontend/binsource/src/main.rs b/js/src/frontend/binsource/src/main.rs >index a69c20faabb0..c33f537b7812 100644 >--- a/js/src/frontend/binsource/src/main.rs >+++ b/js/src/frontend/binsource/src/main.rs >@@ -1,28 +1,29 @@ > extern crate binjs_meta; > extern crate clap; > extern crate env_logger; > extern crate itertools; >-#[macro_use] extern crate log; >+#[macro_use] >+extern crate log; > extern crate webidl; > extern crate yaml_rust; > >-use binjs_meta::export::{ ToWebidl, TypeDeanonymizer, TypeName }; >+use binjs_meta::export::{ToWebidl, TypeDeanonymizer, TypeName}; > use binjs_meta::import::Importer; > use binjs_meta::spec::*; >-use binjs_meta::util:: { Reindentable, ToCases, ToStr }; >+use binjs_meta::util::{Reindentable, ToCases, ToStr}; > >-use std::collections::{ HashMap, HashSet }; >+use std::collections::{HashMap, HashSet}; > use std::fs::*; >-use std::io::{ Read, Write }; >+use std::io::{Read, Write}; > use std::path::Path; > use std::rc::Rc; > >-use clap::{ App, Arg }; >+use clap::{App, Arg}; > > use itertools::Itertools; > > /// Rules for generating the code for parsing a single field > /// of a node. > /// > /// Extracted from the yaml file. > #[derive(Clone, Default)] >@@ -51,17 +52,16 @@ struct FieldRules { > extra_args: Option<Rc<String>>, > } > > #[derive(Clone, Default)] > struct SumRules { > after_arm: Option<String>, > } > >- > /// Rules for generating the code for parsing a full node > /// of a node. > /// > /// Extracted from the yaml file. > #[derive(Clone, Default)] > struct NodeRules { > /// This node inherits from another node. > inherits: Option<NodeName>, >@@ -151,18 +151,17 @@ struct GlobalRules { > /// Documentation for the `BinVariant` class enum. > hpp_tokens_variants_doc: Option<String>, > > /// Per-node rules. > per_node: HashMap<NodeName, NodeRules>, > } > impl GlobalRules { > fn new(syntax: &Spec, yaml: &yaml_rust::yaml::Yaml) -> Self { >- let rules = yaml.as_hash() >- .expect("Rules are not a dictionary"); >+ let rules = yaml.as_hash().expect("Rules are not a dictionary"); > > let mut parser_class_name = None; > let mut parser_class_template = None; > let mut parser_type_ok = None; > let mut parser_default_value = None; > let mut parser_list_append = None; > let mut cpp_header = None; > let mut cpp_footer = None; >@@ -170,17 +169,18 @@ impl GlobalRules { > let mut hpp_tokens_header = None; > let mut hpp_tokens_footer = None; > let mut hpp_tokens_kind_doc = None; > let mut hpp_tokens_field_doc = None; > let mut hpp_tokens_variants_doc = None; > let mut per_node = HashMap::new(); > > for (node_key, node_entries) in rules.iter() { >- let node_key = node_key.as_str() >+ let node_key = node_key >+ .as_str() > .expect("Could not convert node_key to string"); > > match node_key { > "parser" => { > update_rule_rc(&mut parser_class_name, &node_entries["class-name"]) > .unwrap_or_else(|_| panic!("Rule parser.class-name must be a string")); > update_rule(&mut parser_class_template, &node_entries["class-template"]) > .unwrap_or_else(|_| panic!("Rule parser.class-template must be a string")); >@@ -201,202 +201,323 @@ impl GlobalRules { > } > "hpp" => { > update_rule(&mut hpp_class_header, &node_entries["class"]["header"]) > .unwrap_or_else(|_| panic!("Rule hpp.class.header must be a string")); > update_rule(&mut hpp_tokens_header, &node_entries["tokens"]["header"]) > .unwrap_or_else(|_| panic!("Rule hpp.tokens.header must be a string")); > update_rule(&mut hpp_tokens_footer, &node_entries["tokens"]["footer"]) > .unwrap_or_else(|_| panic!("Rule hpp.tokens.footer must be a string")); >- update_rule(&mut hpp_tokens_kind_doc, &node_entries["tokens"]["kind"]["doc"]) >- .unwrap_or_else(|_| panic!("Rule hpp.tokens.kind.doc must be a string")); >- update_rule(&mut hpp_tokens_field_doc, &node_entries["tokens"]["field"]["doc"]) >- .unwrap_or_else(|_| panic!("Rule hpp.tokens.field.doc must be a string")); >- update_rule(&mut hpp_tokens_variants_doc, &node_entries["tokens"]["variants"]["doc"]) >- .unwrap_or_else(|_| panic!("Rule hpp.tokens.variants.doc must be a string")); >+ update_rule( >+ &mut hpp_tokens_kind_doc, >+ &node_entries["tokens"]["kind"]["doc"], >+ ).unwrap_or_else(|_| panic!("Rule hpp.tokens.kind.doc must be a string")); >+ update_rule( >+ &mut hpp_tokens_field_doc, >+ &node_entries["tokens"]["field"]["doc"], >+ ).unwrap_or_else(|_| panic!("Rule hpp.tokens.field.doc must be a string")); >+ update_rule( >+ &mut hpp_tokens_variants_doc, >+ &node_entries["tokens"]["variants"]["doc"], >+ ).unwrap_or_else(|_| panic!("Rule hpp.tokens.variants.doc must be a string")); > continue; > } > _ => {} > } > >- >- let node_name = syntax.get_node_name(&node_key) >+ let node_name = syntax >+ .get_node_name(&node_key) > .unwrap_or_else(|| panic!("Unknown node name {}", node_key)); > >- let hash = node_entries.as_hash() >+ let hash = node_entries >+ .as_hash() > .unwrap_or_else(|| panic!("Node {} isn't a dictionary")); > > let mut node_rule = NodeRules::default(); > for (node_item_key, node_item_entry) in hash { >- let as_string = node_item_key.as_str() >+ let as_string = node_item_key >+ .as_str() > .unwrap_or_else(|| panic!("Keys for rule {} must be strings", node_key)); > match as_string { > "inherits" => { >- let name = node_item_entry.as_str() >- .unwrap_or_else(|| panic!("Rule {}.{} must be a string", node_key, as_string)); >- let inherits = syntax.get_node_name(name) >+ let name = node_item_entry.as_str().unwrap_or_else(|| { >+ panic!("Rule {}.{} must be a string", node_key, as_string) >+ }); >+ let inherits = syntax >+ .get_node_name(name) > .unwrap_or_else(|| panic!("Unknown node name {}", name)); > node_rule.inherits = Some(inherits).cloned(); > } > "extra-params" => { > update_rule_rc(&mut node_rule.extra_params, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ .unwrap_or_else(|()| { >+ panic!("Rule {}.{} must be a string", node_key, as_string) >+ }); > } > "extra-args" => { >- update_rule_rc(&mut node_rule.extra_args, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ update_rule_rc(&mut node_rule.extra_args, node_item_entry).unwrap_or_else( >+ |()| panic!("Rule {}.{} must be a string", node_key, as_string), >+ ); > } > "some" => { > update_rule_rc(&mut node_rule.some_before, &node_item_entry["before"]) >- .unwrap_or_else(|()| panic!("Rule {}.{}.before must be a string", node_key, as_string)); >+ .unwrap_or_else(|()| { >+ panic!("Rule {}.{}.before must be a string", node_key, as_string) >+ }); > update_rule_rc(&mut node_rule.some_after, &node_item_entry["after"]) >- .unwrap_or_else(|()| panic!("Rule {}.{}.after must be a string", node_key, as_string)); >+ .unwrap_or_else(|()| { >+ panic!("Rule {}.{}.after must be a string", node_key, as_string) >+ }); > } > "none" => { > update_rule_rc(&mut node_rule.none_replace, &node_item_entry["replace"]) >- .unwrap_or_else(|()| panic!("Rule {}.{}.replace must be a string", node_key, as_string)); >+ .unwrap_or_else(|()| { >+ panic!("Rule {}.{}.replace must be a string", node_key, as_string) >+ }); > } > "init" => { >- update_rule(&mut node_rule.init, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ update_rule(&mut node_rule.init, node_item_entry).unwrap_or_else(|()| { >+ panic!("Rule {}.{} must be a string", node_key, as_string) >+ }); > } > "build" => { >- update_rule(&mut node_rule.build_result, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ update_rule(&mut node_rule.build_result, node_item_entry).unwrap_or_else( >+ |()| panic!("Rule {}.{} must be a string", node_key, as_string), >+ ); > } > "append" => { >- update_rule(&mut node_rule.append, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ update_rule(&mut node_rule.append, node_item_entry).unwrap_or_else(|()| { >+ panic!("Rule {}.{} must be a string", node_key, as_string) >+ }); > } > "type-ok" => { >- update_rule_rc(&mut node_rule.type_ok, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ update_rule_rc(&mut node_rule.type_ok, node_item_entry).unwrap_or_else( >+ |()| panic!("Rule {}.{} must be a string", node_key, as_string), >+ ); > } > "default-value" => { > update_rule_rc(&mut node_rule.default_value, node_item_entry) >- .unwrap_or_else(|()| panic!("Rule {}.{} must be a string", node_key, as_string)); >+ .unwrap_or_else(|()| { >+ panic!("Rule {}.{} must be a string", node_key, as_string) >+ }); > } > "fields" => { >- let fields = node_item_entry.as_hash() >- .unwrap_or_else(|| panic!("Rule {}.fields must be a hash, got {:?}", node_key, node_entries["fields"])); >+ let fields = node_item_entry.as_hash().unwrap_or_else(|| { >+ panic!( >+ "Rule {}.fields must be a hash, got {:?}", >+ node_key, node_entries["fields"] >+ ) >+ }); > for (field_key, field_entry) in fields { >- let field_key = field_key.as_str() >- .unwrap_or_else(|| panic!("In rule {}, field entries must be field names", >- node_key)) >- .to_string(); >- let field_name = syntax.get_field_name(&field_key) >- .unwrap_or_else(|| panic!("In rule {}, can't find field {}", >- node_key, >- field_key)); >+ let field_key = field_key >+ .as_str() >+ .unwrap_or_else(|| { >+ panic!( >+ "In rule {}, field entries must be field names", >+ node_key >+ ) >+ }).to_string(); >+ let field_name = >+ syntax.get_field_name(&field_key).unwrap_or_else(|| { >+ panic!("In rule {}, can't find field {}", node_key, field_key) >+ }); > > let mut field_rule = FieldRules::default(); >- for (field_config_key, field_config_entry) in field_entry.as_hash() >- .unwrap_or_else(|| panic!("Rule {}.fields.{} must be a hash", node_key, field_key)) >- { >- let field_config_key = field_config_key.as_str() >+ for (field_config_key, field_config_entry) in >+ field_entry.as_hash().unwrap_or_else(|| { >+ panic!("Rule {}.fields.{} must be a hash", node_key, field_key) >+ }) { >+ let field_config_key = field_config_key >+ .as_str() > .expect("Expected a string as a key"); >- match field_config_key >- { >+ match field_config_key { > "block" => { >- update_rule(&mut field_rule.declare, &field_config_entry["declare"]) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "declare")); >+ update_rule( >+ &mut field_rule.declare, >+ &field_config_entry["declare"], >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{}.{} must be a string", >+ node_key, >+ field_key, >+ field_config_key, >+ "declare" >+ ) >+ }, >+ ); > >- update_rule(&mut field_rule.replace, &field_config_entry["replace"]) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "replace")); >+ update_rule( >+ &mut field_rule.replace, >+ &field_config_entry["replace"], >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{}.{} must be a string", >+ node_key, >+ field_key, >+ field_config_key, >+ "replace" >+ ) >+ }, >+ ); > >- update_rule(&mut field_rule.block_before_field, &field_config_entry["before"]) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "before")); >+ update_rule( >+ &mut field_rule.block_before_field, >+ &field_config_entry["before"], >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{}.{} must be a string", >+ node_key, field_key, field_config_key, "before" >+ ) >+ }, >+ ); > >- update_rule(&mut field_rule.block_after_field, &field_config_entry["after"]) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{}.{} must be a string", node_key, field_key, field_config_key, "after")); >+ update_rule( >+ &mut field_rule.block_after_field, >+ &field_config_entry["after"], >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{}.{} must be a string", >+ node_key, field_key, field_config_key, "after" >+ ) >+ }, >+ ); > } > "before" => { >- update_rule(&mut field_rule.before_field, &field_config_entry) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); >+ update_rule( >+ &mut field_rule.before_field, >+ &field_config_entry, >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{} must be a string", >+ node_key, field_key, field_config_key >+ ) >+ }, >+ ); > } > "after" => { >- update_rule(&mut field_rule.after_field, &field_config_entry) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); >+ update_rule( >+ &mut field_rule.after_field, >+ &field_config_entry, >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{} must be a string", >+ node_key, field_key, field_config_key >+ ) >+ }, >+ ); > } > "extra-args" => { >- update_rule_rc(&mut field_rule.extra_args, &field_config_entry) >- .unwrap_or_else(|()| panic!("Rule {}.fields.{}.{} must be a string", node_key, field_key, field_config_key)); >- } >- _ => { >- panic!("Unexpected {}.fields.{}.{}", node_key, field_key, field_config_key) >+ update_rule_rc( >+ &mut field_rule.extra_args, >+ &field_config_entry, >+ ).unwrap_or_else( >+ |()| { >+ panic!( >+ "Rule {}.fields.{}.{} must be a string", >+ node_key, field_key, field_config_key >+ ) >+ }, >+ ); > } >+ _ => panic!( >+ "Unexpected {}.fields.{}.{}", >+ node_key, field_key, field_config_key >+ ), > } > } > node_rule.by_field.insert(field_name.clone(), field_rule); > } > } > "sum-arms" => { >- let arms = node_item_entry.as_hash() >- .unwrap_or_else(|| panic!("Rule {}.sum-arms must be a hash, got {:?}", node_key, node_entries["sum-arms"])); >+ let arms = node_item_entry.as_hash().unwrap_or_else(|| { >+ panic!( >+ "Rule {}.sum-arms must be a hash, got {:?}", >+ node_key, node_entries["sum-arms"] >+ ) >+ }); > for (sum_arm_key, sum_arm_entry) in arms { >- let sum_arm_key = sum_arm_key.as_str() >- .unwrap_or_else(|| panic!("In rule {}, sum arms must be interface names")); >- let sum_arm_name = syntax.get_node_name(&sum_arm_key) >- .unwrap_or_else(|| panic!("In rule {}. cannot find interface {}", node_key, sum_arm_key)); >+ let sum_arm_key = sum_arm_key.as_str().unwrap_or_else(|| { >+ panic!("In rule {}, sum arms must be interface names") >+ }); >+ let sum_arm_name = >+ syntax.get_node_name(&sum_arm_key).unwrap_or_else(|| { >+ panic!( >+ "In rule {}. cannot find interface {}", >+ node_key, sum_arm_key >+ ) >+ }); > > let mut sum_rule = SumRules::default(); >- for (arm_config_key, arm_config_entry) in sum_arm_entry.as_hash() >- .unwrap_or_else(|| panic!("Rule {}.sum-arms.{} must be a hash", node_key, sum_arm_key)) >- { >- let arm_config_key = arm_config_key.as_str() >- .expect("Expected a string as a key"); >- match arm_config_key >- { >+ for (arm_config_key, arm_config_entry) in >+ sum_arm_entry.as_hash().unwrap_or_else(|| { >+ panic!( >+ "Rule {}.sum-arms.{} must be a hash", >+ node_key, sum_arm_key >+ ) >+ }) { >+ let arm_config_key = >+ arm_config_key.as_str().expect("Expected a string as a key"); >+ match arm_config_key { > "after" => { > update_rule(&mut sum_rule.after_arm, arm_config_entry) >- .unwrap_or_else(|()| panic!("Rule {}.sum-arms.{}.{} must be a string", node_key, sum_arm_key, arm_config_key)); >+ .unwrap_or_else(|()| { >+ panic!( >+ "Rule {}.sum-arms.{}.{} must be a string", >+ node_key, sum_arm_key, arm_config_key >+ ) >+ }); > } > _ => { >- panic!("Unexpected {}.sum-arms.{}.{}", node_key, sum_arm_key, arm_config_key); >+ panic!( >+ "Unexpected {}.sum-arms.{}.{}", >+ node_key, sum_arm_key, arm_config_key >+ ); > } > } > } > node_rule.by_sum.insert(sum_arm_name.clone(), sum_rule); > } > } >- _ => panic!("Unexpected node_item_key {}.{}", node_key, as_string) >+ _ => panic!("Unexpected node_item_key {}.{}", node_key, as_string), > } > } > > per_node.insert(node_name.clone(), node_rule); > } > > Self { >- parser_class_name: parser_class_name >- .expect("parser.class-name should be specified"), >+ parser_class_name: parser_class_name.expect("parser.class-name should be specified"), > parser_class_template: Rc::new(if parser_class_template.is_some() { > format!("{} ", parser_class_template.unwrap()) > } else { > "".to_string() > }), >- parser_type_ok: parser_type_ok >- .expect("parser.type-ok should be specified"), >+ parser_type_ok: parser_type_ok.expect("parser.type-ok should be specified"), > parser_default_value: parser_default_value > .expect("parser.default-value should be specified"), > parser_list_append, > cpp_header, > cpp_footer, > hpp_class_header, > hpp_tokens_header, > hpp_tokens_footer, > hpp_tokens_kind_doc, > hpp_tokens_field_doc, > hpp_tokens_variants_doc, > per_node, > } > } > fn get(&self, name: &NodeName) -> NodeRules { >- let mut rules = self.per_node.get(name) >- .cloned() >- .unwrap_or_default(); >+ let mut rules = self.per_node.get(name).cloned().unwrap_or_default(); > if let Some(ref parent) = rules.inherits { > let NodeRules { > inherits: _, > type_ok, > default_value, > extra_params, > extra_args, > some_before, >@@ -434,22 +555,20 @@ impl GlobalRules { > } > if rules.append.is_none() { > rules.append = append; > } > if rules.build_result.is_none() { > rules.build_result = build_result; > } > for (key, value) in by_field { >- rules.by_field.entry(key) >- .or_insert(value); >+ rules.by_field.entry(key).or_insert(value); > } > for (key, value) in by_sum { >- rules.by_sum.entry(key) >- .or_insert(value); >+ rules.by_sum.entry(key).or_insert(value); > } > } > rules > } > } > > /// The inforamtion used to generate a list parser. > struct ListParserData { >@@ -514,85 +633,105 @@ struct CPPExporter { > > impl CPPExporter { > fn new(syntax: Spec, rules: GlobalRules) -> Self { > let mut list_parsers_to_generate = vec![]; > let mut option_parsers_to_generate = vec![]; > for (parser_node_name, typedef) in syntax.typedefs_by_name() { > if typedef.is_optional() { > let content_name = TypeName::type_spec(typedef.spec()); >- let content_node_name = syntax.get_node_name(&content_name) >- .unwrap_or_else(|| panic!("While generating an option parser, could not find node name {}", content_name)) >- .clone(); >+ let content_node_name = syntax >+ .get_node_name(&content_name) >+ .unwrap_or_else(|| { >+ panic!( >+ "While generating an option parser, could not find node name {}", >+ content_name >+ ) >+ }).clone(); > debug!(target: "generate_spidermonkey", "CPPExporter::new adding optional typedef {:?} => {:?} => {:?}", > parser_node_name, > content_name, > content_node_name); > option_parsers_to_generate.push(OptionParserData { > name: parser_node_name.clone(), >- elements: content_node_name >+ elements: content_node_name, > }); >- } else if let TypeSpec::Array { ref contents, ref supports_empty } = *typedef.spec() { >+ } else if let TypeSpec::Array { >+ ref contents, >+ ref supports_empty, >+ } = *typedef.spec() >+ { > let content_name = TypeName::type_(&**contents); >- let content_node_name = syntax.get_node_name(&content_name) >- .unwrap_or_else(|| panic!("While generating an array parser, could not find node name {}", content_name)) >- .clone(); >+ let content_node_name = syntax >+ .get_node_name(&content_name) >+ .unwrap_or_else(|| { >+ panic!( >+ "While generating an array parser, could not find node name {}", >+ content_name >+ ) >+ }).clone(); > list_parsers_to_generate.push(ListParserData { > name: parser_node_name.clone(), > supports_empty: *supports_empty, >- elements: content_node_name >+ elements: content_node_name, > }); > } > } > list_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); > option_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); > > // Prepare variant_by_symbol, which will let us lookup the BinVariant name of > // a symbol. Since some symbols can appear in several enums (e.g. "+" > // is both a unary and a binary operator), we need to collect all the > // string enums that contain each symbol and come up with a unique name > // (note that there is no guarantee of unicity â if collisions show up, > // we may need to tweak the name generation algorithm). >- let mut enum_by_string : HashMap<String, Vec<NodeName>> = HashMap::new(); >- let mut enum_types : HashMap<NodeName, Rc<String>> = HashMap::new(); >+ let mut enum_by_string: HashMap<String, Vec<NodeName>> = HashMap::new(); >+ let mut enum_types: HashMap<NodeName, Rc<String>> = HashMap::new(); > for (name, enum_) in syntax.string_enums_by_name().iter() { >- let type_ = format!("typename {parser_class_name}::{kind}", >- parser_class_name = rules.parser_class_name, >- kind = name.to_class_cases()); >+ let type_ = format!( >+ "typename {parser_class_name}::{kind}", >+ parser_class_name = rules.parser_class_name, >+ kind = name.to_class_cases() >+ ); > enum_types.insert(name.clone(), Rc::new(type_)); > for string in enum_.strings().iter() { >- let vec = enum_by_string.entry(string.clone()) >+ let vec = enum_by_string >+ .entry(string.clone()) > .or_insert_with(|| vec![]); > vec.push(name.clone()); > } > } >- let variants_by_symbol = enum_by_string.drain() >+ let variants_by_symbol = enum_by_string >+ .drain() > .map(|(string, names)| { >- let expanded = format!("{names}{symbol}", >- names = names.iter() >+ let expanded = format!( >+ "{names}{symbol}", >+ names = names >+ .iter() > .map(NodeName::to_str) > .sorted() > .into_iter() > .format("Or"), >- symbol = string.to_cpp_enum_case()); >+ symbol = string.to_cpp_enum_case() >+ ); > (string, expanded) >- }) >- .collect(); >+ }).collect(); > > CPPExporter { > syntax, > rules, > list_parsers_to_generate, > option_parsers_to_generate, > variants_by_symbol, > enum_types, > } > } > >-// ----- Generating the header >+ // ----- Generating the header > > /// Get the type representing a success for parsing this node. > fn get_type_ok(&self, name: &NodeName) -> Rc<String> { > // enum has its own rule. > if self.enum_types.contains_key(name) { > return self.enum_types.get(name).unwrap().clone(); > } > >@@ -612,265 +751,292 @@ impl CPPExporter { > if let Some(type_ok) = rules_for_this_interface.type_ok { > if type_ok.as_str() == "Ok" { > return Rc::new("Ok()".to_string()); > } > } > self.rules.parser_default_value.clone() > } > >- fn get_method_signature(&self, name: &NodeName, prefix: &str, args: &str, >- extra_params: &Option<Rc<String>>) -> String { >+ fn get_method_signature( >+ &self, >+ name: &NodeName, >+ prefix: &str, >+ args: &str, >+ extra_params: &Option<Rc<String>>, >+ ) -> String { > let type_ok = self.get_type_ok(name); > let kind = name.to_class_cases(); > let extra = match extra_params { >- Some(s) => { >- format!("{}\n{}", >- if args.len() > 0 { >- "," >- } else { >- "" >- }, >- s.reindent(" ")) >- } >- _ => { >- "".to_string() >- } >+ Some(s) => format!( >+ "{}\n{}", >+ if args.len() > 0 { "," } else { "" }, >+ s.reindent(" ") >+ ), >+ _ => "".to_string(), > }; >- format!(" JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra});\n", >+ format!( >+ " JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra});\n", > prefix = prefix, > type_ok = type_ok, > kind = kind, > args = args, > extra = extra, > ) > } > >- fn get_method_definition_start(&self, name: &NodeName, prefix: &str, args: &str, >- extra_params: &Option<Rc<String>>) -> String { >+ fn get_method_definition_start( >+ &self, >+ name: &NodeName, >+ prefix: &str, >+ args: &str, >+ extra_params: &Option<Rc<String>>, >+ ) -> String { > let type_ok = self.get_type_ok(name); > let kind = name.to_class_cases(); > let extra = match extra_params { >- Some(s) => { >- format!("{}\n{}", >- if args.len() > 0 { >- "," >- } else { >- "" >- }, >- s.reindent(" ")) >- } >- _ => { >- "".to_string() >- } >+ Some(s) => format!( >+ "{}\n{}", >+ if args.len() > 0 { "," } else { "" }, >+ s.reindent(" ") >+ ), >+ _ => "".to_string(), > }; > format!("{parser_class_template}JS::Result<{type_ok}>\n{parser_class_name}::parse{prefix}{kind}({args}{extra})", > parser_class_template = self.rules.parser_class_template, > prefix = prefix, > type_ok = type_ok, > parser_class_name = self.rules.parser_class_name, > kind = kind, > args = args, > extra = extra, > ) > } > >- fn get_method_call(&self, var_name: &str, name: &NodeName, >- prefix: &str, args: &str, >- extra_params: &Option<Rc<String>>, >- call_kind: MethodCallKind) -> String { >+ fn get_method_call( >+ &self, >+ var_name: &str, >+ name: &NodeName, >+ prefix: &str, >+ args: &str, >+ extra_params: &Option<Rc<String>>, >+ call_kind: MethodCallKind, >+ ) -> String { > let type_ok_is_ok = match call_kind { >- MethodCallKind::Decl | MethodCallKind::Var => { >- self.get_type_ok(name).to_str() == "Ok" >- } >- MethodCallKind::AlwaysDecl | MethodCallKind::AlwaysVar => { >- false >- } >+ MethodCallKind::Decl | MethodCallKind::Var => self.get_type_ok(name).to_str() == "Ok", >+ MethodCallKind::AlwaysDecl | MethodCallKind::AlwaysVar => false, > }; > let extra = match extra_params { >- Some(s) => { >- format!("{}\n{}", >- if args.len() > 0 { >- "," >- } else { >- "" >- }, >- s.reindent(" ")) >- } >- _ => { >- "".to_string() >- } >+ Some(s) => format!( >+ "{}\n{}", >+ if args.len() > 0 { "," } else { "" }, >+ s.reindent(" ") >+ ), >+ _ => "".to_string(), > }; >- let call = format!("parse{prefix}{name}({args}{extra})", >- prefix = prefix, >- name = name.to_class_cases(), >- args = args, >- extra = extra); >+ let call = format!( >+ "parse{prefix}{name}({args}{extra})", >+ prefix = prefix, >+ name = name.to_class_cases(), >+ args = args, >+ extra = extra >+ ); > > if type_ok_is_ok { > // Special case: `Ok` means that we shouldn't bind the return value. >- format!("MOZ_TRY({call});", >- call = call) >+ format!("MOZ_TRY({call});", call = call) > } else { > match call_kind { >- MethodCallKind::Decl | MethodCallKind::AlwaysDecl => { >- format!("BINJS_MOZ_TRY_DECL({var_name}, {call});", >- var_name = var_name, call = call) >- } >- MethodCallKind::Var | MethodCallKind::AlwaysVar => { >- format!("MOZ_TRY_VAR({var_name}, {call});", >- var_name = var_name, call = call) >- } >+ MethodCallKind::Decl | MethodCallKind::AlwaysDecl => format!( >+ "BINJS_MOZ_TRY_DECL({var_name}, {call});", >+ var_name = var_name, >+ call = call >+ ), >+ MethodCallKind::Var | MethodCallKind::AlwaysVar => format!( >+ "MOZ_TRY_VAR({var_name}, {call});", >+ var_name = var_name, >+ call = call >+ ), > } > } > } > > /// Declaring enums for kinds and fields. > fn export_declare_kinds_and_fields_enums(&self, buffer: &mut String) { > buffer.push_str(&self.rules.hpp_tokens_header.reindent("")); > > buffer.push_str("\n\n"); > if self.rules.hpp_tokens_kind_doc.is_some() { > buffer.push_str(&self.rules.hpp_tokens_kind_doc.reindent("")); > } > >- let node_names = self.syntax.node_names() >- .keys() >- .sorted(); >- buffer.push_str(&format!("\n#define FOR_EACH_BIN_KIND(F) \\\n{nodes}\n", >- nodes = node_names.iter() >- .map(|name| format!(" F({enum_name}, \"{spec_name}\")", >+ let node_names = self.syntax.node_names().keys().sorted(); >+ buffer.push_str(&format!( >+ "\n#define FOR_EACH_BIN_KIND(F) \\\n{nodes}\n", >+ nodes = node_names >+ .iter() >+ .map(|name| format!( >+ " F({enum_name}, \"{spec_name}\")", > enum_name = name.to_cpp_enum_case(), >- spec_name = name)) >- .format(" \\\n"))); >- buffer.push_str(" >+ spec_name = name >+ )).format(" \\\n") >+ )); >+ buffer.push_str( >+ " > enum class BinKind { > #define EMIT_ENUM(name, _) name, > FOR_EACH_BIN_KIND(EMIT_ENUM) > #undef EMIT_ENUM > }; >-"); >+", >+ ); > > buffer.push_str(&format!("\n// The number of distinct values of BinKind.\nconst size_t BINKIND_LIMIT = {};\n\n\n", self.syntax.node_names().len())); > buffer.push_str("\n\n"); > if self.rules.hpp_tokens_field_doc.is_some() { > buffer.push_str(&self.rules.hpp_tokens_field_doc.reindent("")); > } > >- let field_names = self.syntax.field_names() >- .keys() >- .sorted(); >- buffer.push_str(&format!("\n#define FOR_EACH_BIN_FIELD(F) \\\n{nodes}\n", >- nodes = field_names.iter() >- .map(|name| format!(" F({enum_name}, \"{spec_name}\")", >+ let field_names = self.syntax.field_names().keys().sorted(); >+ buffer.push_str(&format!( >+ "\n#define FOR_EACH_BIN_FIELD(F) \\\n{nodes}\n", >+ nodes = field_names >+ .iter() >+ .map(|name| format!( >+ " F({enum_name}, \"{spec_name}\")", > spec_name = name, >- enum_name = name.to_cpp_enum_case())) >- .format(" \\\n"))); >- buffer.push_str(" >+ enum_name = name.to_cpp_enum_case() >+ )).format(" \\\n") >+ )); >+ buffer.push_str( >+ " > enum class BinField { > #define EMIT_ENUM(name, _) name, > FOR_EACH_BIN_FIELD(EMIT_ENUM) > #undef EMIT_ENUM > }; >-"); >+", >+ ); > buffer.push_str(&format!("\n// The number of distinct values of BinField.\nconst size_t BINFIELD_LIMIT = {};\n\n\n", self.syntax.field_names().len())); > > if self.rules.hpp_tokens_variants_doc.is_some() { > buffer.push_str(&self.rules.hpp_tokens_variants_doc.reindent("")); > } >- let enum_variants : Vec<_> = self.variants_by_symbol >- .iter() >- .sorted_by(|&(ref symbol_1, ref name_1), &(ref symbol_2, ref name_2)| { >- Ord::cmp(name_1, name_2) >- .then_with(|| Ord::cmp(symbol_1, symbol_2)) >- }); >+ let enum_variants: Vec<_> = self.variants_by_symbol.iter().sorted_by( >+ |&(ref symbol_1, ref name_1), &(ref symbol_2, ref name_2)| { >+ Ord::cmp(name_1, name_2).then_with(|| Ord::cmp(symbol_1, symbol_2)) >+ }, >+ ); > >- buffer.push_str(&format!("\n#define FOR_EACH_BIN_VARIANT(F) \\\n{nodes}\n", >- nodes = enum_variants.into_iter() >- .map(|(symbol, name)| format!(" F({variant_name}, \"{spec_name}\")", >+ buffer.push_str(&format!( >+ "\n#define FOR_EACH_BIN_VARIANT(F) \\\n{nodes}\n", >+ nodes = enum_variants >+ .into_iter() >+ .map(|(symbol, name)| format!( >+ " F({variant_name}, \"{spec_name}\")", > spec_name = symbol, >- variant_name = name)) >- .format(" \\\n"))); >+ variant_name = name >+ )).format(" \\\n") >+ )); > >- buffer.push_str(" >+ buffer.push_str( >+ " > enum class BinVariant { > #define EMIT_ENUM(name, _) name, > FOR_EACH_BIN_VARIANT(EMIT_ENUM) > #undef EMIT_ENUM > }; >-"); >+", >+ ); > buffer.push_str(&format!("\n// The number of distinct values of BinVariant.\nconst size_t BINVARIANT_LIMIT = {};\n\n\n", > self.variants_by_symbol.len())); > > buffer.push_str(&self.rules.hpp_tokens_footer.reindent("")); > buffer.push_str("\n"); > } > > /// Declare string enums > fn export_declare_string_enums_classes(&self, buffer: &mut String) { > buffer.push_str("\n\n// ----- Declaring string enums (by lexicographical order)\n"); >- let string_enums_by_name = self.syntax.string_enums_by_name() >+ let string_enums_by_name = self >+ .syntax >+ .string_enums_by_name() > .iter() > .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); > for (name, enum_) in string_enums_by_name { >- let rendered_cases = enum_.strings() >+ let rendered_cases = enum_ >+ .strings() > .iter() >- .map(|str| format!("{case:<20} /* \"{original}\" */", >- case = str.to_cpp_enum_case(), >- original = str)) >- .format(",\n "); >- let rendered = format!("enum class {name} {{\n {cases}\n}};\n\n", >+ .map(|str| { >+ format!( >+ "{case:<20} /* \"{original}\" */", >+ case = str.to_cpp_enum_case(), >+ original = str >+ ) >+ }).format(",\n "); >+ let rendered = format!( >+ "enum class {name} {{\n {cases}\n}};\n\n", > cases = rendered_cases, >- name = name.to_class_cases()); >+ name = name.to_class_cases() >+ ); > buffer.push_str(&rendered); > } > } > > fn export_declare_sums_of_interface_methods(&self, buffer: &mut String) { >- let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name() >+ let sums_of_interfaces = self >+ .syntax >+ .resolved_sums_of_interfaces_by_name() > .iter() > .sorted_by(|a, b| a.0.cmp(&b.0)); > buffer.push_str("\n\n// ----- Sums of interfaces (by lexicographical order)\n"); > buffer.push_str("// Implementations are autogenerated\n"); > buffer.push_str("// `ParseNode*` may never be nullptr\n"); > for &(ref name, _) in &sums_of_interfaces { > let rules_for_this_sum = self.rules.get(name); > let extra_params = rules_for_this_sum.extra_params; >- let rendered = self.get_method_signature(name, "", "", >- &extra_params); >- buffer.push_str(&rendered.reindent("") >- .newline_if_not_empty()); >+ let rendered = self.get_method_signature(name, "", "", &extra_params); >+ buffer.push_str(&rendered.reindent("").newline_if_not_empty()); > } > for (name, _) in sums_of_interfaces { > let rules_for_this_sum = self.rules.get(name); > let extra_params = rules_for_this_sum.extra_params; >- let rendered = self.get_method_signature(name, "Sum", "const size_t start, const BinKind kind, const BinFields& fields", >- &extra_params); >- buffer.push_str(&rendered.reindent("") >- .newline_if_not_empty()); >+ let rendered = self.get_method_signature( >+ name, >+ "Sum", >+ "const size_t start, const BinKind kind, const BinFields& fields", >+ &extra_params, >+ ); >+ buffer.push_str(&rendered.reindent("").newline_if_not_empty()); > } > } > > fn export_declare_single_interface_methods(&self, buffer: &mut String) { > buffer.push_str("\n\n// ----- Interfaces (by lexicographical order)\n"); > buffer.push_str("// Implementations are autogenerated\n"); > buffer.push_str("// `ParseNode*` may never be nullptr\n"); >- let interfaces_by_name = self.syntax.interfaces_by_name() >+ let interfaces_by_name = self >+ .syntax >+ .interfaces_by_name() > .iter() > .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); > > let mut outer_parsers = Vec::with_capacity(interfaces_by_name.len()); > let mut inner_parsers = Vec::with_capacity(interfaces_by_name.len()); > > for &(name, _) in &interfaces_by_name { > let rules_for_this_interface = self.rules.get(name); > let extra_params = rules_for_this_interface.extra_params; > let outer = self.get_method_signature(name, "", "", &extra_params); >- let inner = self.get_method_signature(name, "Interface", "const size_t start, const BinKind kind, const BinFields& fields", >- &extra_params); >+ let inner = self.get_method_signature( >+ name, >+ "Interface", >+ "const size_t start, const BinKind kind, const BinFields& fields", >+ &extra_params, >+ ); > outer_parsers.push(outer.reindent("")); > inner_parsers.push(inner.reindent("")); > } > > for parser in outer_parsers.drain(..) { > buffer.push_str(&parser); > buffer.push_str("\n"); > } >@@ -879,56 +1045,58 @@ enum class BinVariant { > buffer.push_str(&parser); > buffer.push_str("\n"); > } > } > > fn export_declare_string_enums_methods(&self, buffer: &mut String) { > buffer.push_str("\n\n// ----- String enums (by lexicographical order)\n"); > buffer.push_str("// Implementations are autogenerated\n"); >- let string_enums_by_name = self.syntax.string_enums_by_name() >+ let string_enums_by_name = self >+ .syntax >+ .string_enums_by_name() > .iter() > .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); > for (kind, _) in string_enums_by_name { > let rendered = self.get_method_signature(kind, "", "", &None); > buffer.push_str(&rendered.reindent("")); > buffer.push_str("\n"); > } > } > > fn export_declare_list_methods(&self, buffer: &mut String) { > buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n"); > buffer.push_str("// Implementations are autogenerated\n"); > for parser in &self.list_parsers_to_generate { > let rules_for_this_node = self.rules.get(&parser.name); > let extra_params = rules_for_this_node.extra_params; >- let rendered = self.get_method_signature(&parser.name, "", "", >- &extra_params); >+ let rendered = self.get_method_signature(&parser.name, "", "", &extra_params); > buffer.push_str(&rendered.reindent("")); > buffer.push_str("\n"); > } > } > > fn export_declare_option_methods(&self, buffer: &mut String) { > buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n"); > buffer.push_str("// Implementations are autogenerated\n"); > for parser in &self.option_parsers_to_generate { > let rules_for_this_node = self.rules.get(&parser.name); > let extra_params = rules_for_this_node.extra_params; >- let rendered = self.get_method_signature(&parser.name, "", "", >- &extra_params); >+ let rendered = self.get_method_signature(&parser.name, "", "", &extra_params); > buffer.push_str(&rendered.reindent("")); > buffer.push_str("\n"); > } > } > > fn generate_autogenerated_warning(&self) -> String { >- let warning = format!("// This file was autogenerated by binjs_generate_spidermonkey, >+ let warning = format!( >+ "// This file was autogenerated by binjs_generate_spidermonkey, > // please DO NOT EDIT BY HAND. >-"); >+" >+ ); > warning > } > > /// Generate C++ headers for SpiderMonkey > fn to_spidermonkey_token_hpp(&self) -> String { > let mut buffer = String::new(); > > buffer.push_str(&self.generate_autogenerated_warning()); >@@ -955,88 +1123,112 @@ enum class BinVariant { > > buffer.push_str("\n"); > buffer > } > } > > impl CPPExporter { > /// Generate implementation of a single typesum. >- fn generate_implement_sum(&self, buffer: &mut String, name: &NodeName, nodes: &HashSet<NodeName>) { >+ fn generate_implement_sum( >+ &self, >+ buffer: &mut String, >+ name: &NodeName, >+ nodes: &HashSet<NodeName>, >+ ) { > // Generate comments (FIXME: We should use the actual webidl, not the resolved sum) > let rules_for_this_sum = self.rules.get(name); > let extra_params = rules_for_this_sum.extra_params; > let extra_args = rules_for_this_sum.extra_args; >- let nodes = nodes.iter() >- .sorted(); >+ let nodes = nodes.iter().sorted(); > let kind = name.to_class_cases(); >- let rendered_bnf = format!("/*\n{name} ::= {nodes}\n*/", >- nodes = nodes.iter() >- .format("\n "), >- name = name.to_str()); >+ let rendered_bnf = format!( >+ "/*\n{name} ::= {nodes}\n*/", >+ nodes = nodes.iter().format("\n "), >+ name = name.to_str() >+ ); > > // Generate outer method >- buffer.push_str(&format!("{bnf} >+ buffer.push_str(&format!( >+ "{bnf} > {first_line} > {{ > BinKind kind; > BinFields fields(cx_); > AutoTaggedTuple guard(*tokenizer_); > const auto start = tokenizer_->offset(); > > MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); > > {call} > > MOZ_TRY(guard.done()); > return result; > }}\n", >- bnf = rendered_bnf, >- call = self.get_method_call("result", name, >- "Sum", "start, kind, fields", >- &extra_args, >- MethodCallKind::AlwaysDecl) >- .reindent(" "), >- first_line = self.get_method_definition_start(name, "", "", >- &extra_params) >+ bnf = rendered_bnf, >+ call = self >+ .get_method_call( >+ "result", >+ name, >+ "Sum", >+ "start, kind, fields", >+ &extra_args, >+ MethodCallKind::AlwaysDecl >+ ).reindent(" "), >+ first_line = self.get_method_definition_start(name, "", "", &extra_params) > )); > > // Generate inner method > let mut buffer_cases = String::new(); > for node in nodes { >- buffer_cases.push_str(&format!(" >+ buffer_cases.push_str(&format!( >+ " > case BinKind::{variant_name}: > {call} > {arm_after} break;", >- call = self.get_method_call("result", node, >- "Interface", "start, kind, fields", >- &extra_args, >- MethodCallKind::AlwaysVar) >- .reindent(" "), >+ call = self >+ .get_method_call( >+ "result", >+ node, >+ "Interface", >+ "start, kind, fields", >+ &extra_args, >+ MethodCallKind::AlwaysVar >+ ).reindent(" "), > variant_name = node.to_cpp_enum_case(), >- arm_after = rules_for_this_sum.by_sum.get(&node) >+ arm_after = rules_for_this_sum >+ .by_sum >+ .get(&node) > .cloned() >- .unwrap_or_default().after_arm.reindent(" ") >- .newline_if_not_empty())); >+ .unwrap_or_default() >+ .after_arm >+ .reindent(" ") >+ .newline_if_not_empty() >+ )); > } >- buffer.push_str(&format!("\n{first_line} >+ buffer.push_str(&format!( >+ "\n{first_line} > {{ > {type_ok} result; > switch (kind) {{{cases} > default: > return raiseInvalidKind(\"{kind}\", kind); > }} > return result; > }} > > ", > kind = kind, > cases = buffer_cases, >- first_line = self.get_method_definition_start(name, "Sum", "const size_t start, const BinKind kind, const BinFields& fields", >- &extra_params), >+ first_line = self.get_method_definition_start( >+ name, >+ "Sum", >+ "const size_t start, const BinKind kind, const BinFields& fields", >+ &extra_params >+ ), > type_ok = self.get_type_ok(name) > )); > } > > /// Generate the implementation of a single list parser > fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) { > let rules_for_this_list = self.rules.get(&parser.name); > let extra_params = rules_for_this_list.extra_params; >@@ -1045,82 +1237,89 @@ impl CPPExporter { > // Warn if some rules are unused. > for &(condition, name) in &[ > (rules_for_this_list.build_result.is_some(), "build:"), > (rules_for_this_list.type_ok.is_some(), "type-ok:"), > (rules_for_this_list.by_field.len() > 0, "fields:"), > (rules_for_this_list.by_sum.len() > 0, "sum-arms:"), > ] { > if condition { >- warn!("In {}, rule `{}` was specified but is ignored.", parser.name, name); >+ warn!( >+ "In {}, rule `{}` was specified but is ignored.", >+ parser.name, name >+ ); > } > } > > let kind = parser.name.to_class_cases(); >- let first_line = self.get_method_definition_start(&parser.name, "", "", >- &extra_params); >+ let first_line = self.get_method_definition_start(&parser.name, "", "", &extra_params); > > let init = match rules_for_this_list.init { > Some(str) => str.reindent(" "), > None => { > // We cannot generate the method if we don't know how to initialize the list. >- let rendered = format!(" >+ let rendered = format!( >+ " > {first_line} > {{ > return raiseError(\"FIXME: Not implemented yet ({kind})\"); > }}\n", > first_line = first_line, > kind = kind, > ); > buffer.push_str(&rendered); > return; > } > }; > let append = match rules_for_this_list.append { > Some(str) => str.reindent(" ").newline_if_not_empty(), >- None => { >- match self.rules.parser_list_append { >- Some(ref str) => str.reindent(" ").newline_if_not_empty(), >- None => "".to_string(), >- } >- } >+ None => match self.rules.parser_list_append { >+ Some(ref str) => str.reindent(" ").newline_if_not_empty(), >+ None => "".to_string(), >+ }, > }; > >- >- let rendered = format!("\n{first_line} >+ let rendered = format!( >+ "\n{first_line} > {{ > uint32_t length; > AutoList guard(*tokenizer_); > > const auto start = tokenizer_->offset(); > MOZ_TRY(tokenizer_->enterList(length, guard));{empty_check} > {init} > > for (uint32_t i = 0; i < length; ++i) {{ > {call} > {append} }} > > MOZ_TRY(guard.done()); > return result; > }}\n", > first_line = first_line, >- empty_check = >- if parser.supports_empty { >- "".to_string() >- } else { >- format!("\n if (length == 0)\n return raiseEmpty(\"{kind}\");\n", >- kind = kind) >- }, >- call = self.get_method_call("item", >- &parser.elements, "", "", >- &extra_args, >- MethodCallKind::Decl) >- .reindent(" "), >+ empty_check = if parser.supports_empty { >+ "".to_string() >+ } else { >+ format!( >+ "\n if (length == 0)\n return raiseEmpty(\"{kind}\");\n", >+ kind = kind >+ ) >+ }, >+ call = self >+ .get_method_call( >+ "item", >+ &parser.elements, >+ "", >+ "", >+ &extra_args, >+ MethodCallKind::Decl >+ ).reindent(" "), > init = init, >- append = append); >+ append = append >+ ); > buffer.push_str(&rendered); > } > > fn generate_implement_option(&self, buffer: &mut String, parser: &OptionParserData) { > debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}", > parser.name.to_str(), parser.elements.to_str()); > > let rules_for_this_node = self.rules.get(&parser.name); >@@ -1130,43 +1329,56 @@ impl CPPExporter { > // Warn if some rules are unused. > for &(condition, name) in &[ > (rules_for_this_node.build_result.is_some(), "build:"), > (rules_for_this_node.append.is_some(), "append:"), > (rules_for_this_node.by_field.len() > 0, "fields:"), > (rules_for_this_node.by_sum.len() > 0, "sum-arms:"), > ] { > if condition { >- warn!("In {}, rule `{}` was specified but is ignored.", parser.name, name); >+ warn!( >+ "In {}, rule `{}` was specified but is ignored.", >+ parser.name, name >+ ); > } > } > > let type_ok = self.get_type_ok(&parser.name); > let default_value = self.get_default_value(&parser.name); > > // At this stage, thanks to deanonymization, `contents` > // is something like `OptionalFooBar`. >- let named_implementation = >- if let Some(NamedType::Typedef(ref typedef)) = self.syntax.get_type_by_name(&parser.name) { >- assert!(typedef.is_optional()); >- if let TypeSpec::NamedType(ref named) = *typedef.spec() { >- self.syntax.get_type_by_name(named) >- .unwrap_or_else(|| panic!("Internal error: Could not find type {}, which should have been generated.", named.to_str())) >- } else { >- panic!("Internal error: In {}, type {:?} should have been a named type", >- parser.name.to_str(), >- typedef); >- } >+ let named_implementation = if let Some(NamedType::Typedef(ref typedef)) = >+ self.syntax.get_type_by_name(&parser.name) >+ { >+ assert!(typedef.is_optional()); >+ if let TypeSpec::NamedType(ref named) = *typedef.spec() { >+ self.syntax.get_type_by_name(named).unwrap_or_else(|| { >+ panic!( >+ "Internal error: Could not find type {}, which should have been generated.", >+ named.to_str() >+ ) >+ }) > } else { >- panic!("Internal error: In {}, there should be a type with that name", >- parser.name.to_str()); >- }; >+ panic!( >+ "Internal error: In {}, type {:?} should have been a named type", >+ parser.name.to_str(), >+ typedef >+ ); >+ } >+ } else { >+ panic!( >+ "Internal error: In {}, there should be a type with that name", >+ parser.name.to_str() >+ ); >+ }; > match named_implementation { > NamedType::Interface(_) => { >- buffer.push_str(&format!("{first_line} >+ buffer.push_str(&format!( >+ "{first_line} > {{ > BinKind kind; > BinFields fields(cx_); > AutoTaggedTuple guard(*tokenizer_); > > MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); > {type_ok} result; > if (kind == BinKind::{null}) {{ >@@ -1178,48 +1390,49 @@ impl CPPExporter { > return raiseInvalidKind(\"{kind}\", kind); > }} > MOZ_TRY(guard.done()); > > return result; > }} > > ", >- first_line = self.get_method_definition_start(&parser.name, "", "", >- &extra_params), >+ first_line = >+ self.get_method_definition_start(&parser.name, "", "", &extra_params), > null = self.syntax.get_null_name().to_cpp_enum_case(), >- call = self.get_method_call("result", >- &parser.elements, >- "Interface", "start, kind, fields", >- &extra_args, >- MethodCallKind::AlwaysVar) >- .reindent(" "), >- before = rules_for_this_node.some_before >- .map_or_else(|| "".to_string(), >- |s| s >- .reindent(" ") >- .newline_if_not_empty()), >- after = rules_for_this_node.some_after >- .map_or_else(|| "".to_string(), >- |s| s >- .reindent(" ") >- .newline_if_not_empty()), >- none_block = rules_for_this_node.none_replace >- .map_or_else(|| format!("result = {default_value};", >- default_value = default_value) >- .reindent(" "), >- |s| s.reindent(" ")), >+ call = self >+ .get_method_call( >+ "result", >+ &parser.elements, >+ "Interface", >+ "start, kind, fields", >+ &extra_args, >+ MethodCallKind::AlwaysVar >+ ).reindent(" "), >+ before = rules_for_this_node.some_before.map_or_else( >+ || "".to_string(), >+ |s| s.reindent(" ").newline_if_not_empty() >+ ), >+ after = rules_for_this_node.some_after.map_or_else( >+ || "".to_string(), >+ |s| s.reindent(" ").newline_if_not_empty() >+ ), >+ none_block = rules_for_this_node.none_replace.map_or_else( >+ || format!("result = {default_value};", default_value = default_value) >+ .reindent(" "), >+ |s| s.reindent(" ") >+ ), > type_ok = type_ok, > kind = parser.elements.to_cpp_enum_case(), > )); > } >- NamedType::Typedef(ref type_) => { >- match type_.spec() { >- &TypeSpec::TypeSum(_) => { >- buffer.push_str(&format!("{first_line} >+ NamedType::Typedef(ref type_) => match type_.spec() { >+ &TypeSpec::TypeSum(_) => { >+ buffer.push_str(&format!( >+ "{first_line} > {{ > BinKind kind; > BinFields fields(cx_); > AutoTaggedTuple guard(*tokenizer_); > > MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); > {type_ok} result; > if (kind == BinKind::{null}) {{ >@@ -1229,99 +1442,108 @@ impl CPPExporter { > {before}{call}{after} > }} > MOZ_TRY(guard.done()); > > return result; > }} > > ", >- first_line = self.get_method_definition_start(&parser.name, "", "", >- &extra_params), >- call = self.get_method_call("result", &parser.elements, >- "Sum", "start, kind, fields", >- &extra_args, >- MethodCallKind::AlwaysVar) >+ first_line = >+ self.get_method_definition_start(&parser.name, "", "", &extra_params), >+ call = self >+ .get_method_call( >+ "result", >+ &parser.elements, >+ "Sum", >+ "start, kind, fields", >+ &extra_args, >+ MethodCallKind::AlwaysVar >+ ).reindent(" "), >+ before = rules_for_this_node.some_before.map_or_else( >+ || "".to_string(), >+ |s| s.reindent(" ").newline_if_not_empty() >+ ), >+ after = rules_for_this_node.some_after.map_or_else( >+ || "".to_string(), >+ |s| s.reindent(" ").newline_if_not_empty() >+ ), >+ none_block = rules_for_this_node.none_replace.map_or_else( >+ || format!("result = {default_value};", default_value = default_value) > .reindent(" "), >- before = rules_for_this_node.some_before >- .map_or_else(|| "".to_string(), >- |s| s >- .reindent(" ") >- .newline_if_not_empty()), >- after = rules_for_this_node.some_after >- .map_or_else(|| "".to_string(), >- |s| s >- .reindent(" ") >- .newline_if_not_empty()), >- none_block = rules_for_this_node.none_replace >- .map_or_else(|| format!("result = {default_value};", >- default_value = default_value) >- .reindent(" "), >- |s| s.reindent(" ")), >- type_ok = type_ok, >- null = self.syntax.get_null_name().to_cpp_enum_case(), >- )); >- } >- &TypeSpec::String => { >- let build_result = rules_for_this_node.init.reindent(" "); >- let first_line = self.get_method_definition_start(&parser.name, "", "", >- &extra_params); >- if build_result.len() == 0 { >- buffer.push_str(&format!("{first_line} >+ |s| s.reindent(" ") >+ ), >+ type_ok = type_ok, >+ null = self.syntax.get_null_name().to_cpp_enum_case(), >+ )); >+ } >+ &TypeSpec::String => { >+ let build_result = rules_for_this_node.init.reindent(" "); >+ let first_line = >+ self.get_method_definition_start(&parser.name, "", "", &extra_params); >+ if build_result.len() == 0 { >+ buffer.push_str(&format!( >+ "{first_line} > {{ > return raiseError(\"FIXME: Not implemented yet ({kind})\"); > }} > > ", >- first_line = first_line, >- kind = parser.name.to_str())); >- } else { >- buffer.push_str(&format!("{first_line} >+ first_line = first_line, >+ kind = parser.name.to_str() >+ )); >+ } else { >+ buffer.push_str(&format!( >+ "{first_line} > {{ > BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom()); > > {build} > > return result; > }} > > ", >- first_line = first_line, >- build = build_result, >- )); >- } >+ first_line = first_line, >+ build = build_result, >+ )); > } >- _else => unimplemented!("{:?}", _else) > } >- } >- NamedType::StringEnum(_) => { >- unimplemented!() >- } >+ _else => unimplemented!("{:?}", _else), >+ }, >+ NamedType::StringEnum(_) => unimplemented!(), > } > } > >- fn generate_implement_interface(&self, buffer: &mut String, name: &NodeName, interface: &Interface) { >+ fn generate_implement_interface( >+ &self, >+ buffer: &mut String, >+ name: &NodeName, >+ interface: &Interface, >+ ) { > let rules_for_this_interface = self.rules.get(name); > let extra_params = rules_for_this_interface.extra_params; > let extra_args = rules_for_this_interface.extra_args; > >- for &(condition, rule_name) in &[ >- (rules_for_this_interface.append.is_some(), "build:"), >- ] { >+ for &(condition, rule_name) in &[(rules_for_this_interface.append.is_some(), "build:")] { > if condition { >- warn!("In {}, rule `{}` was specified but is ignored.", name, rule_name); >+ warn!( >+ "In {}, rule `{}` was specified but is ignored.", >+ name, rule_name >+ ); > } > } > > // Generate comments > let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", " ")); > buffer.push_str(&comment); > > // Generate public method >- buffer.push_str(&format!("{first_line} >+ buffer.push_str(&format!( >+ "{first_line} > {{ > BinKind kind; > BinFields fields(cx_); > AutoTaggedTuple guard(*tokenizer_); > > MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); > if (kind != BinKind::{kind}) {{ > return raiseInvalidKind(\"{kind}\", kind); >@@ -1329,180 +1551,265 @@ impl CPPExporter { > const auto start = tokenizer_->offset(); > {call} > MOZ_TRY(guard.done()); > > return result; > }} > > ", >- first_line = self.get_method_definition_start(name, "", "", >- &extra_params), >+ first_line = self.get_method_definition_start(name, "", "", &extra_params), > kind = name.to_cpp_enum_case(), >- call = self.get_method_call("result", name, >- "Interface", "start, kind, fields", >- &extra_args, >- MethodCallKind::AlwaysDecl) >- .reindent(" ") >+ call = self >+ .get_method_call( >+ "result", >+ name, >+ "Interface", >+ "start, kind, fields", >+ &extra_args, >+ MethodCallKind::AlwaysDecl >+ ).reindent(" ") > )); > > // Generate aux method > let number_of_fields = interface.contents().fields().len(); >- let first_line = self.get_method_definition_start(name, "Interface", "const size_t start, const BinKind kind, const BinFields& fields", >- &extra_params); >+ let first_line = self.get_method_definition_start( >+ name, >+ "Interface", >+ "const size_t start, const BinKind kind, const BinFields& fields", >+ &extra_params, >+ ); > >- let fields_type_list = format!("{{ {} }}", interface.contents() >- .fields() >- .iter() >- .map(|field| format!("BinField::{}", field.name().to_cpp_enum_case())) >- .format(", ")); >+ let fields_type_list = format!( >+ "{{ {} }}", >+ interface >+ .contents() >+ .fields() >+ .iter() >+ .map(|field| format!("BinField::{}", field.name().to_cpp_enum_case())) >+ .format(", ") >+ ); > > let mut fields_implem = String::new(); > for field in interface.contents().fields() { >- let rules_for_this_field = rules_for_this_interface.by_field.get(field.name()) >+ let rules_for_this_field = rules_for_this_interface >+ .by_field >+ .get(field.name()) > .cloned() > .unwrap_or_default(); >- let needs_block = rules_for_this_field.block_before_field.is_some() || rules_for_this_field.block_after_field.is_some(); >+ let needs_block = rules_for_this_field.block_before_field.is_some() >+ || rules_for_this_field.block_after_field.is_some(); > > let var_name = field.name().to_cpp_field_case(); > let (decl_var, parse_var) = match field.type_().get_primitive(&self.syntax) { >- Some(IsNullable { is_nullable: false, content: Primitive::Number }) => { >+ Some(IsNullable { >+ is_nullable: false, >+ content: Primitive::Number, >+ }) => { > if needs_block { >- (Some(format!("double {var_name};", var_name = var_name)), >- Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readDouble());", var_name = var_name))) >+ ( >+ Some(format!("double {var_name};", var_name = var_name)), >+ Some(format!( >+ "MOZ_TRY_VAR({var_name}, tokenizer_->readDouble());", >+ var_name = var_name >+ )), >+ ) > } else { >- (None, >- Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble());", var_name = var_name))) >+ ( >+ None, >+ Some(format!( >+ "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble());", >+ var_name = var_name >+ )), >+ ) > } > } >- Some(IsNullable { is_nullable: false, content: Primitive::Boolean }) => { >+ Some(IsNullable { >+ is_nullable: false, >+ content: Primitive::Boolean, >+ }) => { > if needs_block { >- (Some(format!("bool {var_name};", var_name = var_name)), >- Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readBool());", var_name = var_name))) >+ ( >+ Some(format!("bool {var_name};", var_name = var_name)), >+ Some(format!( >+ "MOZ_TRY_VAR({var_name}, tokenizer_->readBool());", >+ var_name = var_name >+ )), >+ ) > } else { >- (None, >- Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool());", var_name = var_name))) >+ ( >+ None, >+ Some(format!( >+ "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool());", >+ var_name = var_name >+ )), >+ ) > } > } >- Some(IsNullable { is_nullable: false, content: Primitive::Offset }) => { >+ Some(IsNullable { >+ is_nullable: false, >+ content: Primitive::Offset, >+ }) => { > if needs_block { >- (Some(format!("BinTokenReaderBase::SkippableSubTree {var_name};", var_name = var_name)), >- Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree());", var_name = var_name))) >+ ( >+ Some(format!( >+ "BinTokenReaderBase::SkippableSubTree {var_name};", >+ var_name = var_name >+ )), >+ Some(format!( >+ "MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree());", >+ var_name = var_name >+ )), >+ ) > } else { > (None, > Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readSkippableSubTree());", var_name = var_name))) > } > } >- Some(IsNullable { content: Primitive::Void, .. }) => { >+ Some(IsNullable { >+ content: Primitive::Void, >+ .. >+ }) => { > warn!("Internal error: We shouldn't have any `void` types at this stage."); >- (Some(format!("// Skipping void field {}", field.name().to_str())), >- None) >- } >- Some(IsNullable { is_nullable: false, content: Primitive::String }) => { >- (Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), >- Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readAtom());", var_name = var_name))) >+ ( >+ Some(format!("// Skipping void field {}", field.name().to_str())), >+ None, >+ ) > } >+ Some(IsNullable { >+ is_nullable: false, >+ content: Primitive::String, >+ }) => ( >+ Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), >+ Some(format!( >+ "MOZ_TRY_VAR({var_name}, tokenizer_->readAtom());", >+ var_name = var_name >+ )), >+ ), > _else => { > let typename = TypeName::type_(field.type_()); >- let name = self.syntax.get_node_name(typename.to_str()) >+ let name = self >+ .syntax >+ .get_node_name(typename.to_str()) > .expect("NodeName for the field type should exist."); > let field_extra_args = rules_for_this_field.extra_args; > > let (decl_var, call_kind) = if needs_block { >- (Some(format!("{typename} {var_name};", >- var_name = var_name, >- typename = typename)), >- MethodCallKind::Var) >+ ( >+ Some(format!( >+ "{typename} {var_name};", >+ var_name = var_name, >+ typename = typename >+ )), >+ MethodCallKind::Var, >+ ) > } else { >- (None, >- MethodCallKind::Decl) >+ (None, MethodCallKind::Decl) > }; > >- (decl_var, >- Some(self.get_method_call(var_name.to_str(), >- &name, "", "", &field_extra_args, >- call_kind))) >+ ( >+ decl_var, >+ Some(self.get_method_call( >+ var_name.to_str(), >+ &name, >+ "", >+ "", >+ &field_extra_args, >+ call_kind, >+ )), >+ ) > } > }; > > let rendered = { > if rules_for_this_field.replace.is_some() { > for &(condition, rule_name) in &[ > (rules_for_this_field.before_field.is_some(), "before:"), > (rules_for_this_field.after_field.is_some(), "after:"), > (rules_for_this_field.declare.is_some(), "declare:"), > ] { > if condition { > warn!("In {}, rule `{}` was specified but is ignored because `replace:` is also specified.", name, rule_name); > } > } >- rules_for_this_field.replace.reindent(" ") >- .newline() >+ rules_for_this_field.replace.reindent(" ").newline() > } else { > let before_field = rules_for_this_field.before_field.reindent(" "); > let after_field = rules_for_this_field.after_field.reindent(" "); > let decl_var = if rules_for_this_field.declare.is_some() { > rules_for_this_field.declare.reindent(" ") > } else { > decl_var.reindent(" ") > }; > if needs_block { > let parse_var = parse_var.reindent(" "); >- format!("{before_field}{decl_var} {{ >+ format!( >+ "{before_field}{decl_var} {{ > {block_before_field}{parse_var}{block_after_field} > }} > {after_field}", > before_field = before_field.reindent(" ").newline_if_not_empty(), > decl_var = decl_var.reindent(" ").newline_if_not_empty(), >- block_before_field = rules_for_this_field.block_before_field.reindent(" ").newline_if_not_empty(), >+ block_before_field = rules_for_this_field >+ .block_before_field >+ .reindent(" ") >+ .newline_if_not_empty(), > parse_var = parse_var.reindent(" ").newline_if_not_empty(), >- block_after_field = rules_for_this_field.block_after_field.reindent(" "), >- after_field = after_field.reindent(" ")) >+ block_after_field = >+ rules_for_this_field.block_after_field.reindent(" "), >+ after_field = after_field.reindent(" ") >+ ) > } else { > // We have a before_field and an after_field. This will create newlines > // for them. >- format!(" >+ format!( >+ " > {before_field}{decl_var}{parse_var}{after_field}", > before_field = before_field.reindent(" ").newline_if_not_empty(), > decl_var = decl_var.reindent(" ").newline_if_not_empty(), > parse_var = parse_var.reindent(" ").newline_if_not_empty(), >- after_field = after_field.reindent(" ")) >+ after_field = after_field.reindent(" ") >+ ) > } > } > }; > fields_implem.push_str(&rendered); > } > > let init = rules_for_this_interface.init.reindent(" "); > let build_result = rules_for_this_interface.build_result.reindent(" "); > > if build_result == "" { >- buffer.push_str(&format!("{first_line} >+ buffer.push_str(&format!( >+ "{first_line} > {{ > return raiseError(\"FIXME: Not implemented yet ({class_name})\"); > }} > > ", > class_name = name.to_class_cases(), > first_line = first_line, > )); > } else { > let check_fields = if number_of_fields == 0 { > format!("MOZ_TRY(tokenizer_->checkFields0(kind, fields));") > } else { > // The following strategy is designed for old versions of clang. >- format!(" >+ format!( >+ " > #if defined(DEBUG) > const BinField expected_fields[{number_of_fields}] = {fields_type_list}; > MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields)); > #endif // defined(DEBUG)", > fields_type_list = fields_type_list, >- number_of_fields = number_of_fields) >+ number_of_fields = number_of_fields >+ ) > }; >- buffer.push_str(&format!("{first_line} >+ buffer.push_str(&format!( >+ "{first_line} > {{ > MOZ_ASSERT(kind == BinKind::{kind}); > BINJS_TRY(CheckRecursionLimit(cx_)); > {check_fields} > {pre}{fields_implem} > {post} return result; > }} > >@@ -1523,84 +1830,93 @@ impl CPPExporter { > > buffer.push_str(&self.generate_autogenerated_warning()); > > // 0. Header > buffer.push_str(&self.rules.cpp_header.reindent("")); > buffer.push_str("\n"); > > // 1. Typesums >- buffer.push_str("\n\n// ----- Sums of interfaces (autogenerated, by lexicographical order)\n"); >+ buffer.push_str( >+ "\n\n// ----- Sums of interfaces (autogenerated, by lexicographical order)\n", >+ ); > buffer.push_str("// Sums of sums are flattened.\n"); > >- let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name() >+ let sums_of_interfaces = self >+ .syntax >+ .resolved_sums_of_interfaces_by_name() > .iter() > .sorted_by(|a, b| a.0.cmp(&b.0)); > > for (name, nodes) in sums_of_interfaces { > self.generate_implement_sum(&mut buffer, name, nodes); > } > > // 2. Single interfaces > buffer.push_str("\n\n// ----- Interfaces (autogenerated, by lexicographical order)\n"); > buffer.push_str("// When fields have a non-trivial type, implementation is deanonymized and delegated to another parser.\n"); >- let interfaces_by_name = self.syntax.interfaces_by_name() >+ let interfaces_by_name = self >+ .syntax >+ .interfaces_by_name() > .iter() > .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); > > for (name, interface) in interfaces_by_name { > self.generate_implement_interface(&mut buffer, name, interface); > } > > // 3. String Enums > buffer.push_str("\n\n// ----- String enums (autogenerated, by lexicographical order)\n"); > { >- let string_enums_by_name = self.syntax.string_enums_by_name() >+ let string_enums_by_name = self >+ .syntax >+ .string_enums_by_name() > .iter() > .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); > for (kind, enum_) in string_enums_by_name { >- let convert = format!(" switch (variant) {{ >+ let convert = format!( >+ " switch (variant) {{ > {cases} > default: > return raiseInvalidVariant(\"{kind}\", variant); > }}", > kind = kind, >- cases = enum_.strings() >+ cases = enum_ >+ .strings() > .iter() >- .map(|symbol| { >- format!(" case BinVariant::{binvariant_variant}: >+ .map(|symbol| format!( >+ " case BinVariant::{binvariant_variant}: > return {kind}::{specialized_variant};", >- kind = kind, >- specialized_variant = symbol.to_cpp_enum_case(), >- binvariant_variant = self.variants_by_symbol.get(symbol) >- .unwrap() >- ) >- }) >- .format("\n") >+ kind = kind, >+ specialized_variant = symbol.to_cpp_enum_case(), >+ binvariant_variant = self.variants_by_symbol.get(symbol).unwrap() >+ )).format("\n") > ); > >- let rendered_doc = format!("/*\nenum {kind} {{\n{cases}\n}};\n*/\n", >+ let rendered_doc = format!( >+ "/*\nenum {kind} {{\n{cases}\n}};\n*/\n", > kind = kind, >- cases = enum_.strings() >- .iter() >- .map(|s| format!(" \"{}\"", s)) >- .format(",\n") >+ cases = enum_ >+ .strings() >+ .iter() >+ .map(|s| format!(" \"{}\"", s)) >+ .format(",\n") > ); >- buffer.push_str(&format!("{rendered_doc}{first_line} >+ buffer.push_str(&format!( >+ "{rendered_doc}{first_line} > {{ > BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); > > {convert} > }} > > ", > rendered_doc = rendered_doc, > convert = convert, >- first_line = self.get_method_definition_start(kind, "", "", >- &None) >+ first_line = self.get_method_definition_start(kind, "", "", &None) > )); > } > } > > // 4. Lists > buffer.push_str("\n\n// ----- Lists (autogenerated, by lexicographical order)\n"); > for parser in &self.list_parsers_to_generate { > self.generate_implement_list(&mut buffer, parser); >@@ -1617,25 +1933,28 @@ impl CPPExporter { > buffer.push_str("\n"); > > buffer > } > } > > fn update_rule(rule: &mut Option<String>, entry: &yaml_rust::Yaml) -> Result<Option<()>, ()> { > if entry.is_badvalue() { >- return Ok(None) >+ return Ok(None); > } else if let Some(as_str) = entry.as_str() { > *rule = Some(as_str.to_string()); > Ok(Some(())) > } else { > Err(()) > } > } >-fn update_rule_rc(rule: &mut Option<Rc<String>>, entry: &yaml_rust::Yaml) -> Result<Option<()>, ()> { >+fn update_rule_rc( >+ rule: &mut Option<Rc<String>>, >+ entry: &yaml_rust::Yaml, >+) -> Result<Option<()>, ()> { > let mut value = None; > let ret = update_rule(&mut value, entry)?; > if let Some(s) = value { > *rule = Some(Rc::new(s)); > } > Ok(ret) > } > >@@ -1665,105 +1984,116 @@ fn main() { > Arg::with_name("OUT_IMPL_FILE") > .long("out-impl") > .required(true) > .takes_value(true) > .help("Output implementation file (.cpp)"), > ]) > .get_matches(); > >- let source_path = matches.value_of("INPUT.webidl") >+ let source_path = matches >+ .value_of("INPUT.webidl") > .expect("Expected INPUT.webidl"); > >- let mut file = File::open(source_path) >- .expect("Could not open source"); >+ let mut file = File::open(source_path).expect("Could not open source"); > let mut source = String::new(); > file.read_to_string(&mut source) > .expect("Could not read source"); > > println!("...parsing webidl"); >- let ast = webidl::parse_string(&source) >- .expect("Could not parse source"); >+ let ast = webidl::parse_string(&source).expect("Could not parse source"); > > println!("...verifying grammar"); > let mut builder = Importer::import(&ast); > let fake_root = builder.node_name("@@ROOT@@"); // Unused > let null = builder.node_name(""); // Used >- builder.add_interface(&null) >- .unwrap(); >+ builder.add_interface(&null).unwrap(); > let syntax = builder.into_spec(SpecOptions { > root: &fake_root, > null: &null, > }); > > let deanonymizer = TypeDeanonymizer::new(&syntax); > let syntax_options = SpecOptions { > root: &fake_root, > null: &null, > }; > let new_syntax = deanonymizer.into_spec(syntax_options); > > let rules_source_path = matches.value_of("INPUT.yaml").unwrap(); > println!("...generating rules"); >- let mut file = File::open(rules_source_path) >- .expect("Could not open rules"); >+ let mut file = File::open(rules_source_path).expect("Could not open rules"); > let mut data = String::new(); > file.read_to_string(&mut data) > .expect("Could not read rules"); > >- let yaml = yaml_rust::YamlLoader::load_from_str(&data) >- .expect("Could not parse rules"); >+ let yaml = yaml_rust::YamlLoader::load_from_str(&data).expect("Could not parse rules"); > assert_eq!(yaml.len(), 1); > > let global_rules = GlobalRules::new(&new_syntax, &yaml[0]); > let exporter = CPPExporter::new(new_syntax, global_rules); > > let get_file_content = |path: &str| { > if !Path::new(path).is_file() { > return None; > } > >- let mut f = File::open(path) >- .expect("File not found"); >+ let mut f = File::open(path).expect("File not found"); > let mut contents = String::new(); > f.read_to_string(&mut contents) > .expect("Failed to read file"); > Some(contents) > }; > let write_to = |description, arg, data: &String| { >- let dest_path = matches.value_of(arg) >- .unwrap(); >- print!("...exporting {description}: {path} ... ", >+ let dest_path = matches.value_of(arg).unwrap(); >+ print!( >+ "...exporting {description}: {path} ... ", > description = description, >- path = dest_path); >+ path = dest_path >+ ); > > if let Some(old_data) = get_file_content(dest_path) { > if old_data == *data { > // To avoid unnecessary rebuild, do not touch the file if the > // content is not updated. > println!("skip"); > return; > } > }; > >- let mut dest = File::create(&dest_path) >- .unwrap_or_else(|e| panic!("Could not create {description} at {path}: {error}", >- description = description, >- path = dest_path, >- error = e)); >- dest.write_all(data.as_bytes()) >- .unwrap_or_else(|e| panic!("Could not write {description} at {path}: {error}", >- description = description, >- path = dest_path, >- error = e)); >+ let mut dest = File::create(&dest_path).unwrap_or_else(|e| { >+ panic!( >+ "Could not create {description} at {path}: {error}", >+ description = description, >+ path = dest_path, >+ error = e >+ ) >+ }); >+ dest.write_all(data.as_bytes()).unwrap_or_else(|e| { >+ panic!( >+ "Could not write {description} at {path}: {error}", >+ description = description, >+ path = dest_path, >+ error = e >+ ) >+ }); > > println!("done"); > }; > >- write_to("C++ class header code", "OUT_HEADER_CLASS_FILE", >- &exporter.to_spidermonkey_class_hpp()); >- write_to("C++ token header code", "OUT_TOKEN_FILE", >- &exporter.to_spidermonkey_token_hpp()); >- write_to("C++ token implementation code", "OUT_IMPL_FILE", >- &exporter.to_spidermonkey_cpp()); >+ write_to( >+ "C++ class header code", >+ "OUT_HEADER_CLASS_FILE", >+ &exporter.to_spidermonkey_class_hpp(), >+ ); >+ write_to( >+ "C++ token header code", >+ "OUT_TOKEN_FILE", >+ &exporter.to_spidermonkey_token_hpp(), >+ ); >+ write_to( >+ "C++ token implementation code", >+ "OUT_IMPL_FILE", >+ &exporter.to_spidermonkey_cpp(), >+ ); > > println!("...done"); > } >diff --git a/js/src/lib.rs b/js/src/lib.rs >index d8f6ce78db7e..390dfe414163 100644 >--- a/js/src/lib.rs >+++ b/js/src/lib.rs >@@ -1,2 +1 @@ > extern crate libz_sys; >- >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs >index 2972eba0d664..1d4c2e636372 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_funcs.rs >@@ -1,159 +1,219 @@ > // This code is generated. > > use super::*; > > #[cfg(feature = "dlopen")] > macro_rules! cstr { >- ($x:expr) => { concat!($x, "\0").as_bytes().as_ptr() as *const c_char } >+ ($x:expr) => { >+ concat!($x, "\0").as_bytes().as_ptr() as *const c_char >+ }; > } > > #[cfg(not(feature = "dlopen"))] > mod static_fns { > use super::*; > use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void}; > > #[link(name = "pulse")] > extern "C" { > pub fn pa_get_library_version() -> *const c_char; > pub fn pa_channel_map_can_balance(map: *const pa_channel_map) -> c_int; > pub fn pa_channel_map_init(m: *mut pa_channel_map) -> *mut pa_channel_map; >- pub fn pa_context_connect(c: *mut pa_context, >- server: *const c_char, >- flags: pa_context_flags_t, >- api: *const pa_spawn_api) >- -> c_int; >+ pub fn pa_context_connect( >+ c: *mut pa_context, >+ server: *const c_char, >+ flags: pa_context_flags_t, >+ api: *const pa_spawn_api, >+ ) -> c_int; > pub fn pa_context_disconnect(c: *mut pa_context); >- pub fn pa_context_drain(c: *mut pa_context, >- cb: pa_context_notify_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_get_server_info(c: *const pa_context, >- cb: pa_server_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_get_sink_info_by_name(c: *const pa_context, >- name: *const c_char, >- cb: pa_sink_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_get_sink_info_list(c: *const pa_context, >- cb: pa_sink_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_get_sink_input_info(c: *const pa_context, >- idx: u32, >- cb: pa_sink_input_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_get_source_info_list(c: *const pa_context, >- cb: pa_source_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >+ pub fn pa_context_drain( >+ c: *mut pa_context, >+ cb: pa_context_notify_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_get_server_info( >+ c: *const pa_context, >+ cb: pa_server_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_get_sink_info_by_name( >+ c: *const pa_context, >+ name: *const c_char, >+ cb: pa_sink_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_get_sink_info_list( >+ c: *const pa_context, >+ cb: pa_sink_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_get_sink_input_info( >+ c: *const pa_context, >+ idx: u32, >+ cb: pa_sink_input_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_get_source_info_list( >+ c: *const pa_context, >+ cb: pa_source_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; > pub fn pa_context_get_state(c: *const pa_context) -> pa_context_state_t; >- pub fn pa_context_new(mainloop: *mut pa_mainloop_api, name: *const c_char) -> *mut pa_context; >- pub fn pa_context_rttime_new(c: *const pa_context, >- usec: pa_usec_t, >- cb: pa_time_event_cb_t, >- userdata: *mut c_void) >- -> *mut pa_time_event; >- pub fn pa_context_set_sink_input_volume(c: *mut pa_context, >- idx: u32, >- volume: *const pa_cvolume, >- cb: pa_context_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >- pub fn pa_context_set_state_callback(c: *mut pa_context, cb: pa_context_notify_cb_t, userdata: *mut c_void); >+ pub fn pa_context_new( >+ mainloop: *mut pa_mainloop_api, >+ name: *const c_char, >+ ) -> *mut pa_context; >+ pub fn pa_context_rttime_new( >+ c: *const pa_context, >+ usec: pa_usec_t, >+ cb: pa_time_event_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_time_event; >+ pub fn pa_context_set_sink_input_volume( >+ c: *mut pa_context, >+ idx: u32, >+ volume: *const pa_cvolume, >+ cb: pa_context_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; >+ pub fn pa_context_set_state_callback( >+ c: *mut pa_context, >+ cb: pa_context_notify_cb_t, >+ userdata: *mut c_void, >+ ); > pub fn pa_context_errno(c: *mut pa_context) -> c_int; >- pub fn pa_context_set_subscribe_callback(c: *mut pa_context, >- cb: pa_context_subscribe_cb_t, >- userdata: *mut c_void); >- pub fn pa_context_subscribe(c: *mut pa_context, >- m: pa_subscription_mask_t, >- cb: pa_context_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >+ pub fn pa_context_set_subscribe_callback( >+ c: *mut pa_context, >+ cb: pa_context_subscribe_cb_t, >+ userdata: *mut c_void, >+ ); >+ pub fn pa_context_subscribe( >+ c: *mut pa_context, >+ m: pa_subscription_mask_t, >+ cb: pa_context_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; > pub fn pa_context_ref(c: *mut pa_context) -> *mut pa_context; > pub fn pa_context_unref(c: *mut pa_context); >- pub fn pa_cvolume_set(a: *mut pa_cvolume, channels: c_uint, v: pa_volume_t) -> *mut pa_cvolume; >- pub fn pa_cvolume_set_balance(v: *mut pa_cvolume, >- map: *const pa_channel_map, >- new_balance: c_float) >- -> *mut pa_cvolume; >+ pub fn pa_cvolume_set( >+ a: *mut pa_cvolume, >+ channels: c_uint, >+ v: pa_volume_t, >+ ) -> *mut pa_cvolume; >+ pub fn pa_cvolume_set_balance( >+ v: *mut pa_cvolume, >+ map: *const pa_channel_map, >+ new_balance: c_float, >+ ) -> *mut pa_cvolume; > pub fn pa_frame_size(spec: *const pa_sample_spec) -> usize; >- pub fn pa_mainloop_api_once(m: *mut pa_mainloop_api, >- callback: pa_mainloop_api_once_cb_t, >- userdata: *mut c_void); >+ pub fn pa_mainloop_api_once( >+ m: *mut pa_mainloop_api, >+ callback: pa_mainloop_api_once_cb_t, >+ userdata: *mut c_void, >+ ); > pub fn pa_strerror(error: pa_error_code_t) -> *const c_char; > pub fn pa_operation_ref(o: *mut pa_operation) -> *mut pa_operation; > pub fn pa_operation_unref(o: *mut pa_operation); > pub fn pa_operation_cancel(o: *mut pa_operation); > pub fn pa_operation_get_state(o: *const pa_operation) -> pa_operation_state_t; >- pub fn pa_operation_set_state_callback(o: *mut pa_operation, >- cb: pa_operation_notify_cb_t, >- userdata: *mut c_void); >+ pub fn pa_operation_set_state_callback( >+ o: *mut pa_operation, >+ cb: pa_operation_notify_cb_t, >+ userdata: *mut c_void, >+ ); > pub fn pa_proplist_gets(p: *mut pa_proplist, key: *const c_char) -> *const c_char; > pub fn pa_rtclock_now() -> pa_usec_t; >- pub fn pa_stream_begin_write(p: *mut pa_stream, data: *mut *mut c_void, nbytes: *mut usize) -> c_int; >+ pub fn pa_stream_begin_write( >+ p: *mut pa_stream, >+ data: *mut *mut c_void, >+ nbytes: *mut usize, >+ ) -> c_int; > pub fn pa_stream_cancel_write(p: *mut pa_stream) -> c_int; > pub fn pa_stream_is_suspended(s: *const pa_stream) -> c_int; > pub fn pa_stream_is_corked(s: *const pa_stream) -> c_int; >- pub fn pa_stream_connect_playback(s: *mut pa_stream, >- dev: *const c_char, >- attr: *const pa_buffer_attr, >- flags: pa_stream_flags_t, >- volume: *const pa_cvolume, >- sync_stream: *const pa_stream) >- -> c_int; >- pub fn pa_stream_connect_record(s: *mut pa_stream, >- dev: *const c_char, >- attr: *const pa_buffer_attr, >- flags: pa_stream_flags_t) >- -> c_int; >- pub fn pa_stream_cork(s: *mut pa_stream, >- b: c_int, >- cb: pa_stream_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >+ pub fn pa_stream_connect_playback( >+ s: *mut pa_stream, >+ dev: *const c_char, >+ attr: *const pa_buffer_attr, >+ flags: pa_stream_flags_t, >+ volume: *const pa_cvolume, >+ sync_stream: *const pa_stream, >+ ) -> c_int; >+ pub fn pa_stream_connect_record( >+ s: *mut pa_stream, >+ dev: *const c_char, >+ attr: *const pa_buffer_attr, >+ flags: pa_stream_flags_t, >+ ) -> c_int; >+ pub fn pa_stream_cork( >+ s: *mut pa_stream, >+ b: c_int, >+ cb: pa_stream_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; > pub fn pa_stream_disconnect(s: *mut pa_stream) -> c_int; > pub fn pa_stream_drop(p: *mut pa_stream) -> c_int; > pub fn pa_stream_get_buffer_attr(s: *const pa_stream) -> *const pa_buffer_attr; > pub fn pa_stream_get_channel_map(s: *const pa_stream) -> *const pa_channel_map; > pub fn pa_stream_get_device_name(s: *const pa_stream) -> *const c_char; > pub fn pa_stream_get_index(s: *const pa_stream) -> u32; >- pub fn pa_stream_get_latency(s: *const pa_stream, r_usec: *mut pa_usec_t, negative: *mut c_int) -> c_int; >+ pub fn pa_stream_get_latency( >+ s: *const pa_stream, >+ r_usec: *mut pa_usec_t, >+ negative: *mut c_int, >+ ) -> c_int; > pub fn pa_stream_get_sample_spec(s: *const pa_stream) -> *const pa_sample_spec; > pub fn pa_stream_get_state(p: *const pa_stream) -> pa_stream_state_t; > pub fn pa_stream_get_context(s: *const pa_stream) -> *mut pa_context; > pub fn pa_stream_get_time(s: *const pa_stream, r_usec: *mut pa_usec_t) -> c_int; >- pub fn pa_stream_new(c: *mut pa_context, >- name: *const c_char, >- ss: *const pa_sample_spec, >- map: *const pa_channel_map) >- -> *mut pa_stream; >- pub fn pa_stream_peek(p: *mut pa_stream, data: *mut *const c_void, nbytes: *mut usize) -> c_int; >+ pub fn pa_stream_new( >+ c: *mut pa_context, >+ name: *const c_char, >+ ss: *const pa_sample_spec, >+ map: *const pa_channel_map, >+ ) -> *mut pa_stream; >+ pub fn pa_stream_peek( >+ p: *mut pa_stream, >+ data: *mut *const c_void, >+ nbytes: *mut usize, >+ ) -> c_int; > pub fn pa_stream_readable_size(p: *const pa_stream) -> usize; >- pub fn pa_stream_set_state_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void); >- pub fn pa_stream_set_write_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void); >- pub fn pa_stream_set_read_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void); >+ pub fn pa_stream_set_state_callback( >+ s: *mut pa_stream, >+ cb: pa_stream_notify_cb_t, >+ userdata: *mut c_void, >+ ); >+ pub fn pa_stream_set_write_callback( >+ p: *mut pa_stream, >+ cb: pa_stream_request_cb_t, >+ userdata: *mut c_void, >+ ); >+ pub fn pa_stream_set_read_callback( >+ p: *mut pa_stream, >+ cb: pa_stream_request_cb_t, >+ userdata: *mut c_void, >+ ); > pub fn pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream; > pub fn pa_stream_unref(s: *mut pa_stream); >- pub fn pa_stream_update_timing_info(p: *mut pa_stream, >- cb: pa_stream_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation; >+ pub fn pa_stream_update_timing_info( >+ p: *mut pa_stream, >+ cb: pa_stream_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation; > pub fn pa_stream_writable_size(p: *const pa_stream) -> usize; >- pub fn pa_stream_write(p: *mut pa_stream, >- data: *const c_void, >- nbytes: usize, >- free_cb: pa_free_cb_t, >- offset: i64, >- seek: pa_seek_mode_t) >- -> c_int; >+ pub fn pa_stream_write( >+ p: *mut pa_stream, >+ data: *const c_void, >+ nbytes: usize, >+ free_cb: pa_free_cb_t, >+ offset: i64, >+ seek: pa_seek_mode_t, >+ ) -> c_int; > pub fn pa_sw_volume_from_linear(v: c_double) -> pa_volume_t; > pub fn pa_threaded_mainloop_free(m: *mut pa_threaded_mainloop); > pub fn pa_threaded_mainloop_get_api(m: *mut pa_threaded_mainloop) -> *mut pa_mainloop_api; > pub fn pa_threaded_mainloop_in_thread(m: *mut pa_threaded_mainloop) -> c_int; > pub fn pa_threaded_mainloop_lock(m: *mut pa_threaded_mainloop); > pub fn pa_threaded_mainloop_new() -> *mut pa_threaded_mainloop; > pub fn pa_threaded_mainloop_signal(m: *mut pa_threaded_mainloop, wait_for_accept: c_int); > pub fn pa_threaded_mainloop_start(m: *mut pa_threaded_mainloop) -> c_int; >@@ -166,17 +226,17 @@ mod static_fns { > } > > #[cfg(not(feature = "dlopen"))] > pub use self::static_fns::*; > > #[cfg(feature = "dlopen")] > mod dynamic_fns { > use super::*; >- use libc::{RTLD_LAZY, dlclose, dlopen, dlsym}; >+ use libc::{dlclose, dlopen, dlsym, RTLD_LAZY}; > use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void}; > > #[derive(Debug)] > pub struct LibLoader { > _lib: *mut ::libc::c_void, > } > > impl LibLoader { >@@ -707,19 +767,17 @@ mod dynamic_fns { > PA_XREALLOC = { > let fp = dlsym(h, cstr!("pa_xrealloc")); > if fp.is_null() { > return None; > } > fp > }; > >- Some(LibLoader { >- _lib: h, >- }) >+ Some(LibLoader { _lib: h }) > } > } > > impl ::std::ops::Drop for LibLoader { > #[inline] > fn drop(&mut self) { > unsafe { > dlclose(self._lib); >@@ -731,276 +789,315 @@ mod dynamic_fns { > #[inline] > pub unsafe fn pa_get_library_version() -> *const c_char { > (::std::mem::transmute::<_, extern "C" fn() -> *const c_char>(PA_GET_LIBRARY_VERSION))() > } > > static mut PA_CHANNEL_MAP_CAN_BALANCE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_channel_map_can_balance(map: *const pa_channel_map) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_channel_map) -> c_int>(PA_CHANNEL_MAP_CAN_BALANCE))(map) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_channel_map) -> c_int>( >+ PA_CHANNEL_MAP_CAN_BALANCE, >+ ))(map) > } > > static mut PA_CHANNEL_MAP_INIT: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_channel_map_init(m: *mut pa_channel_map) -> *mut pa_channel_map { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_channel_map) -> *mut pa_channel_map>(PA_CHANNEL_MAP_INIT))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_channel_map) -> *mut pa_channel_map>( >+ PA_CHANNEL_MAP_INIT, >+ ))(m) > } > > static mut PA_CONTEXT_CONNECT: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_connect(c: *mut pa_context, >- server: *const c_char, >- flags: pa_context_flags_t, >- api: *const pa_spawn_api) >- -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- *const c_char, >- pa_context_flags_t, >- *const pa_spawn_api) >- -> c_int>(PA_CONTEXT_CONNECT))(c, server, flags, api) >+ pub unsafe fn pa_context_connect( >+ c: *mut pa_context, >+ server: *const c_char, >+ flags: pa_context_flags_t, >+ api: *const pa_spawn_api, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_context, *const c_char, pa_context_flags_t, *const pa_spawn_api) >+ -> c_int, >+ >(PA_CONTEXT_CONNECT))(c, server, flags, api) > } > > static mut PA_CONTEXT_DISCONNECT: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_context_disconnect(c: *mut pa_context) { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_context)>(PA_CONTEXT_DISCONNECT))(c) > } > > static mut PA_CONTEXT_DRAIN: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_drain(c: *mut pa_context, >- cb: pa_context_notify_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, pa_context_notify_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_DRAIN))(c, cb, userdata) >+ pub unsafe fn pa_context_drain( >+ c: *mut pa_context, >+ cb: pa_context_notify_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_context, pa_context_notify_cb_t, *mut c_void) >+ -> *mut pa_operation, >+ >(PA_CONTEXT_DRAIN))(c, cb, userdata) > } > > static mut PA_CONTEXT_GET_SERVER_INFO: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_get_server_info(c: *const pa_context, >- cb: pa_server_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, pa_server_info_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_GET_SERVER_INFO))(c, cb, userdata) >+ pub unsafe fn pa_context_get_server_info( >+ c: *const pa_context, >+ cb: pa_server_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, pa_server_info_cb_t, *mut c_void) -> *mut pa_operation, >+ >(PA_CONTEXT_GET_SERVER_INFO))(c, cb, userdata) > } > > static mut PA_CONTEXT_GET_SINK_INFO_BY_NAME: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_get_sink_info_by_name(c: *const pa_context, >- name: *const c_char, >- cb: pa_sink_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, >- *const c_char, >- pa_sink_info_cb_t, >- *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_GET_SINK_INFO_BY_NAME))(c, >- name, >- cb, >- userdata) >+ pub unsafe fn pa_context_get_sink_info_by_name( >+ c: *const pa_context, >+ name: *const c_char, >+ cb: pa_sink_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, *const c_char, pa_sink_info_cb_t, *mut c_void) >+ -> *mut pa_operation, >+ >(PA_CONTEXT_GET_SINK_INFO_BY_NAME))(c, name, cb, userdata) > } > > static mut PA_CONTEXT_GET_SINK_INFO_LIST: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_get_sink_info_list(c: *const pa_context, >- cb: pa_sink_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, pa_sink_info_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_GET_SINK_INFO_LIST))(c, cb, userdata) >+ pub unsafe fn pa_context_get_sink_info_list( >+ c: *const pa_context, >+ cb: pa_sink_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, pa_sink_info_cb_t, *mut c_void) -> *mut pa_operation, >+ >(PA_CONTEXT_GET_SINK_INFO_LIST))(c, cb, userdata) > } > > static mut PA_CONTEXT_GET_SINK_INPUT_INFO: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_get_sink_input_info(c: *const pa_context, >- idx: u32, >- cb: pa_sink_input_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, u32, pa_sink_input_info_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_GET_SINK_INPUT_INFO))(c, >- idx, >- cb, >- userdata) >+ pub unsafe fn pa_context_get_sink_input_info( >+ c: *const pa_context, >+ idx: u32, >+ cb: pa_sink_input_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, u32, pa_sink_input_info_cb_t, *mut c_void) >+ -> *mut pa_operation, >+ >(PA_CONTEXT_GET_SINK_INPUT_INFO))(c, idx, cb, userdata) > } > > static mut PA_CONTEXT_GET_SOURCE_INFO_LIST: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_get_source_info_list(c: *const pa_context, >- cb: pa_source_info_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, pa_source_info_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_GET_SOURCE_INFO_LIST))(c, cb, userdata) >+ pub unsafe fn pa_context_get_source_info_list( >+ c: *const pa_context, >+ cb: pa_source_info_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, pa_source_info_cb_t, *mut c_void) -> *mut pa_operation, >+ >(PA_CONTEXT_GET_SOURCE_INFO_LIST))(c, cb, userdata) > } > > static mut PA_CONTEXT_GET_STATE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_context_get_state(c: *const pa_context) -> pa_context_state_t { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_context) -> pa_context_state_t>(PA_CONTEXT_GET_STATE))(c) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_context) -> pa_context_state_t>( >+ PA_CONTEXT_GET_STATE, >+ ))(c) > } > > static mut PA_CONTEXT_NEW: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_new(mainloop: *mut pa_mainloop_api, name: *const c_char) -> *mut pa_context { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_mainloop_api, *const c_char) >- -> *mut pa_context>(PA_CONTEXT_NEW))(mainloop, name) >+ pub unsafe fn pa_context_new( >+ mainloop: *mut pa_mainloop_api, >+ name: *const c_char, >+ ) -> *mut pa_context { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_mainloop_api, *const c_char) -> *mut pa_context, >+ >(PA_CONTEXT_NEW))(mainloop, name) > } > > static mut PA_CONTEXT_RTTIME_NEW: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_rttime_new(c: *const pa_context, >- usec: pa_usec_t, >- cb: pa_time_event_cb_t, >- userdata: *mut c_void) >- -> *mut pa_time_event { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_context, >- pa_usec_t, >- pa_time_event_cb_t, >- *mut c_void) >- -> *mut pa_time_event>(PA_CONTEXT_RTTIME_NEW))(c, usec, cb, userdata) >+ pub unsafe fn pa_context_rttime_new( >+ c: *const pa_context, >+ usec: pa_usec_t, >+ cb: pa_time_event_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_time_event { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_context, pa_usec_t, pa_time_event_cb_t, *mut c_void) >+ -> *mut pa_time_event, >+ >(PA_CONTEXT_RTTIME_NEW))(c, usec, cb, userdata) > } > > static mut PA_CONTEXT_SET_SINK_INPUT_VOLUME: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_set_sink_input_volume(c: *mut pa_context, >- idx: u32, >- volume: *const pa_cvolume, >- cb: pa_context_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- u32, >- *const pa_cvolume, >- pa_context_success_cb_t, >- *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_SET_SINK_INPUT_VOLUME))(c, >- idx, >- volume, >- cb, >- userdata) >+ pub unsafe fn pa_context_set_sink_input_volume( >+ c: *mut pa_context, >+ idx: u32, >+ volume: *const pa_cvolume, >+ cb: pa_context_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn( >+ *mut pa_context, >+ u32, >+ *const pa_cvolume, >+ pa_context_success_cb_t, >+ *mut c_void, >+ ) -> *mut pa_operation, >+ >(PA_CONTEXT_SET_SINK_INPUT_VOLUME))(c, idx, volume, cb, userdata) > } > > static mut PA_CONTEXT_SET_STATE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_set_state_callback(c: *mut pa_context, >- cb: pa_context_notify_cb_t, >- userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- pa_context_notify_cb_t, >- *mut c_void)>(PA_CONTEXT_SET_STATE_CALLBACK))(c, cb, userdata) >+ pub unsafe fn pa_context_set_state_callback( >+ c: *mut pa_context, >+ cb: pa_context_notify_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_context, pa_context_notify_cb_t, *mut c_void), >+ >(PA_CONTEXT_SET_STATE_CALLBACK))(c, cb, userdata) > } > > static mut PA_CONTEXT_ERRNO: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_context_errno(c: *mut pa_context) -> c_int { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_context) -> c_int>(PA_CONTEXT_ERRNO))(c) > } > > static mut PA_CONTEXT_SET_SUBSCRIBE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_set_subscribe_callback(c: *mut pa_context, >- cb: pa_context_subscribe_cb_t, >- userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- pa_context_subscribe_cb_t, >- *mut c_void)>(PA_CONTEXT_SET_SUBSCRIBE_CALLBACK))(c, cb, userdata) >+ pub unsafe fn pa_context_set_subscribe_callback( >+ c: *mut pa_context, >+ cb: pa_context_subscribe_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_context, pa_context_subscribe_cb_t, *mut c_void), >+ >(PA_CONTEXT_SET_SUBSCRIBE_CALLBACK))(c, cb, userdata) > } > > static mut PA_CONTEXT_SUBSCRIBE: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_context_subscribe(c: *mut pa_context, >- m: pa_subscription_mask_t, >- cb: pa_context_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- pa_subscription_mask_t, >- pa_context_success_cb_t, >- *mut c_void) >- -> *mut pa_operation>(PA_CONTEXT_SUBSCRIBE))(c, m, cb, userdata) >+ pub unsafe fn pa_context_subscribe( >+ c: *mut pa_context, >+ m: pa_subscription_mask_t, >+ cb: pa_context_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn( >+ *mut pa_context, >+ pa_subscription_mask_t, >+ pa_context_success_cb_t, >+ *mut c_void, >+ ) -> *mut pa_operation, >+ >(PA_CONTEXT_SUBSCRIBE))(c, m, cb, userdata) > } > > static mut PA_CONTEXT_REF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_context_ref(c: *mut pa_context) -> *mut pa_context { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_context) -> *mut pa_context>(PA_CONTEXT_REF))(c) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_context) -> *mut pa_context>( >+ PA_CONTEXT_REF, >+ ))(c) > } > > static mut PA_CONTEXT_UNREF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_context_unref(c: *mut pa_context) { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_context)>(PA_CONTEXT_UNREF))(c) > } > > static mut PA_CVOLUME_SET: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_cvolume_set(a: *mut pa_cvolume, channels: c_uint, v: pa_volume_t) -> *mut pa_cvolume { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_cvolume, c_uint, pa_volume_t) >- -> *mut pa_cvolume>(PA_CVOLUME_SET))(a, channels, v) >+ pub unsafe fn pa_cvolume_set( >+ a: *mut pa_cvolume, >+ channels: c_uint, >+ v: pa_volume_t, >+ ) -> *mut pa_cvolume { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_cvolume, c_uint, pa_volume_t) -> *mut pa_cvolume, >+ >(PA_CVOLUME_SET))(a, channels, v) > } > > static mut PA_CVOLUME_SET_BALANCE: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_cvolume_set_balance(v: *mut pa_cvolume, >- map: *const pa_channel_map, >- new_balance: c_float) >- -> *mut pa_cvolume { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_cvolume, >- *const pa_channel_map, >- c_float) >- -> *mut pa_cvolume>(PA_CVOLUME_SET_BALANCE))(v, map, new_balance) >+ pub unsafe fn pa_cvolume_set_balance( >+ v: *mut pa_cvolume, >+ map: *const pa_channel_map, >+ new_balance: c_float, >+ ) -> *mut pa_cvolume { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_cvolume, *const pa_channel_map, c_float) -> *mut pa_cvolume, >+ >(PA_CVOLUME_SET_BALANCE))(v, map, new_balance) > } > > static mut PA_FRAME_SIZE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_frame_size(spec: *const pa_sample_spec) -> usize { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_sample_spec) -> usize>(PA_FRAME_SIZE))(spec) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_sample_spec) -> usize>(PA_FRAME_SIZE))( >+ spec, >+ ) > } > > static mut PA_MAINLOOP_API_ONCE: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_mainloop_api_once(m: *mut pa_mainloop_api, >- callback: pa_mainloop_api_once_cb_t, >- userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_mainloop_api, >- pa_mainloop_api_once_cb_t, >- *mut c_void)>(PA_MAINLOOP_API_ONCE))(m, callback, userdata) >+ pub unsafe fn pa_mainloop_api_once( >+ m: *mut pa_mainloop_api, >+ callback: pa_mainloop_api_once_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_mainloop_api, pa_mainloop_api_once_cb_t, *mut c_void), >+ >(PA_MAINLOOP_API_ONCE))(m, callback, userdata) > } > > static mut PA_STRERROR: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_strerror(error: pa_error_code_t) -> *const c_char { >- (::std::mem::transmute::<_, extern "C" fn(pa_error_code_t) -> *const c_char>(PA_STRERROR))(error) >+ (::std::mem::transmute::<_, extern "C" fn(pa_error_code_t) -> *const c_char>(PA_STRERROR))( >+ error, >+ ) > } > > static mut PA_OPERATION_REF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_operation_ref(o: *mut pa_operation) -> *mut pa_operation { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation) -> *mut pa_operation>(PA_OPERATION_REF))(o) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation) -> *mut pa_operation>( >+ PA_OPERATION_REF, >+ ))(o) > } > > static mut PA_OPERATION_UNREF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_operation_unref(o: *mut pa_operation) { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation)>(PA_OPERATION_UNREF))(o) > } > >@@ -1008,390 +1105,463 @@ mod dynamic_fns { > #[inline] > pub unsafe fn pa_operation_cancel(o: *mut pa_operation) { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_operation)>(PA_OPERATION_CANCEL))(o) > } > > static mut PA_OPERATION_GET_STATE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_operation_get_state(o: *const pa_operation) -> pa_operation_state_t { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_operation) >- -> pa_operation_state_t>(PA_OPERATION_GET_STATE))(o) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_operation) -> pa_operation_state_t>( >+ PA_OPERATION_GET_STATE, >+ ))(o) > } > > static mut PA_OPERATION_SET_STATE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_operation_set_state_callback(o: *mut pa_operation, >- cb: pa_operation_notify_cb_t, >- userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_operation, >- pa_operation_notify_cb_t, >- *mut c_void)>(PA_OPERATION_SET_STATE_CALLBACK))(o, cb, userdata) >+ pub unsafe fn pa_operation_set_state_callback( >+ o: *mut pa_operation, >+ cb: pa_operation_notify_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_operation, pa_operation_notify_cb_t, *mut c_void), >+ >(PA_OPERATION_SET_STATE_CALLBACK))(o, cb, userdata) > } > > static mut PA_PROPLIST_GETS: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_proplist_gets(p: *mut pa_proplist, key: *const c_char) -> *const c_char { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_proplist, *const c_char) >- -> *const c_char>(PA_PROPLIST_GETS))(p, key) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_proplist, *const c_char) -> *const c_char>( >+ PA_PROPLIST_GETS, >+ ))(p, key) > } > > static mut PA_RTCLOCK_NOW: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_rtclock_now() -> pa_usec_t { > (::std::mem::transmute::<_, extern "C" fn() -> pa_usec_t>(PA_RTCLOCK_NOW))() > } > > static mut PA_STREAM_BEGIN_WRITE: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_begin_write(p: *mut pa_stream, data: *mut *mut c_void, nbytes: *mut usize) -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- *mut *mut c_void, >- *mut usize) >- -> c_int>(PA_STREAM_BEGIN_WRITE))(p, data, nbytes) >+ pub unsafe fn pa_stream_begin_write( >+ p: *mut pa_stream, >+ data: *mut *mut c_void, >+ nbytes: *mut usize, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, *mut *mut c_void, *mut usize) -> c_int, >+ >(PA_STREAM_BEGIN_WRITE))(p, data, nbytes) > } > > static mut PA_STREAM_CANCEL_WRITE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_cancel_write(p: *mut pa_stream) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_CANCEL_WRITE))(p) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_CANCEL_WRITE))( >+ p, >+ ) > } > > static mut PA_STREAM_IS_SUSPENDED: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_is_suspended(s: *const pa_stream) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>(PA_STREAM_IS_SUSPENDED))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>( >+ PA_STREAM_IS_SUSPENDED, >+ ))(s) > } > > static mut PA_STREAM_IS_CORKED: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_is_corked(s: *const pa_stream) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>(PA_STREAM_IS_CORKED))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> c_int>(PA_STREAM_IS_CORKED))( >+ s, >+ ) > } > > static mut PA_STREAM_CONNECT_PLAYBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_connect_playback(s: *mut pa_stream, >- dev: *const c_char, >- attr: *const pa_buffer_attr, >- flags: pa_stream_flags_t, >- volume: *const pa_cvolume, >- sync_stream: *const pa_stream) >- -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- *const c_char, >- *const pa_buffer_attr, >- pa_stream_flags_t, >- *const pa_cvolume, >- *const pa_stream) >- -> c_int>(PA_STREAM_CONNECT_PLAYBACK))(s, >- dev, >- attr, >- flags, >- volume, >- sync_stream) >+ pub unsafe fn pa_stream_connect_playback( >+ s: *mut pa_stream, >+ dev: *const c_char, >+ attr: *const pa_buffer_attr, >+ flags: pa_stream_flags_t, >+ volume: *const pa_cvolume, >+ sync_stream: *const pa_stream, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn( >+ *mut pa_stream, >+ *const c_char, >+ *const pa_buffer_attr, >+ pa_stream_flags_t, >+ *const pa_cvolume, >+ *const pa_stream, >+ ) -> c_int, >+ >(PA_STREAM_CONNECT_PLAYBACK))(s, dev, attr, flags, volume, sync_stream) > } > > static mut PA_STREAM_CONNECT_RECORD: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_connect_record(s: *mut pa_stream, >- dev: *const c_char, >- attr: *const pa_buffer_attr, >- flags: pa_stream_flags_t) >- -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- *const c_char, >- *const pa_buffer_attr, >- pa_stream_flags_t) >- -> c_int>(PA_STREAM_CONNECT_RECORD))(s, dev, attr, flags) >+ pub unsafe fn pa_stream_connect_record( >+ s: *mut pa_stream, >+ dev: *const c_char, >+ attr: *const pa_buffer_attr, >+ flags: pa_stream_flags_t, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, *const c_char, *const pa_buffer_attr, pa_stream_flags_t) >+ -> c_int, >+ >(PA_STREAM_CONNECT_RECORD))(s, dev, attr, flags) > } > > static mut PA_STREAM_CORK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_cork(s: *mut pa_stream, >- b: c_int, >- cb: pa_stream_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, c_int, pa_stream_success_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_STREAM_CORK))(s, b, cb, userdata) >+ pub unsafe fn pa_stream_cork( >+ s: *mut pa_stream, >+ b: c_int, >+ cb: pa_stream_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, c_int, pa_stream_success_cb_t, *mut c_void) >+ -> *mut pa_operation, >+ >(PA_STREAM_CORK))(s, b, cb, userdata) > } > > static mut PA_STREAM_DISCONNECT: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_disconnect(s: *mut pa_stream) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_DISCONNECT))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_DISCONNECT))( >+ s, >+ ) > } > > static mut PA_STREAM_DROP: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_drop(p: *mut pa_stream) -> c_int { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> c_int>(PA_STREAM_DROP))(p) > } > > static mut PA_STREAM_GET_BUFFER_ATTR: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_buffer_attr(s: *const pa_stream) -> *const pa_buffer_attr { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_stream) >- -> *const pa_buffer_attr>(PA_STREAM_GET_BUFFER_ATTR))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *const pa_buffer_attr>( >+ PA_STREAM_GET_BUFFER_ATTR, >+ ))(s) > } > > static mut PA_STREAM_GET_CHANNEL_MAP: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_channel_map(s: *const pa_stream) -> *const pa_channel_map { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_stream) >- -> *const pa_channel_map>(PA_STREAM_GET_CHANNEL_MAP))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *const pa_channel_map>( >+ PA_STREAM_GET_CHANNEL_MAP, >+ ))(s) > } > > static mut PA_STREAM_GET_DEVICE_NAME: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_device_name(s: *const pa_stream) -> *const c_char { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *const c_char>(PA_STREAM_GET_DEVICE_NAME))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *const c_char>( >+ PA_STREAM_GET_DEVICE_NAME, >+ ))(s) > } > > static mut PA_STREAM_GET_INDEX: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_index(s: *const pa_stream) -> u32 { > (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> u32>(PA_STREAM_GET_INDEX))(s) > } > > static mut PA_STREAM_GET_LATENCY: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_get_latency(s: *const pa_stream, r_usec: *mut pa_usec_t, negative: *mut c_int) -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_stream, >- *mut pa_usec_t, >- *mut c_int) >- -> c_int>(PA_STREAM_GET_LATENCY))(s, r_usec, negative) >+ pub unsafe fn pa_stream_get_latency( >+ s: *const pa_stream, >+ r_usec: *mut pa_usec_t, >+ negative: *mut c_int, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*const pa_stream, *mut pa_usec_t, *mut c_int) -> c_int, >+ >(PA_STREAM_GET_LATENCY))(s, r_usec, negative) > } > > static mut PA_STREAM_GET_SAMPLE_SPEC: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_sample_spec(s: *const pa_stream) -> *const pa_sample_spec { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_stream) >- -> *const pa_sample_spec>(PA_STREAM_GET_SAMPLE_SPEC))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *const pa_sample_spec>( >+ PA_STREAM_GET_SAMPLE_SPEC, >+ ))(s) > } > > static mut PA_STREAM_GET_STATE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_state(p: *const pa_stream) -> pa_stream_state_t { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> pa_stream_state_t>(PA_STREAM_GET_STATE))(p) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> pa_stream_state_t>( >+ PA_STREAM_GET_STATE, >+ ))(p) > } > > static mut PA_STREAM_GET_CONTEXT: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_context(s: *const pa_stream) -> *mut pa_context { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *mut pa_context>(PA_STREAM_GET_CONTEXT))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> *mut pa_context>( >+ PA_STREAM_GET_CONTEXT, >+ ))(s) > } > > static mut PA_STREAM_GET_TIME: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_get_time(s: *const pa_stream, r_usec: *mut pa_usec_t) -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*const pa_stream, *mut pa_usec_t) >- -> c_int>(PA_STREAM_GET_TIME))(s, r_usec) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream, *mut pa_usec_t) -> c_int>( >+ PA_STREAM_GET_TIME, >+ ))(s, r_usec) > } > > static mut PA_STREAM_NEW: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_new(c: *mut pa_context, >- name: *const c_char, >- ss: *const pa_sample_spec, >- map: *const pa_channel_map) >- -> *mut pa_stream { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_context, >- *const c_char, >- *const pa_sample_spec, >- *const pa_channel_map) >- -> *mut pa_stream>(PA_STREAM_NEW))(c, name, ss, map) >+ pub unsafe fn pa_stream_new( >+ c: *mut pa_context, >+ name: *const c_char, >+ ss: *const pa_sample_spec, >+ map: *const pa_channel_map, >+ ) -> *mut pa_stream { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn( >+ *mut pa_context, >+ *const c_char, >+ *const pa_sample_spec, >+ *const pa_channel_map, >+ ) -> *mut pa_stream, >+ >(PA_STREAM_NEW))(c, name, ss, map) > } > > static mut PA_STREAM_PEEK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_peek(p: *mut pa_stream, data: *mut *const c_void, nbytes: *mut usize) -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- *mut *const c_void, >- *mut usize) >- -> c_int>(PA_STREAM_PEEK))(p, data, nbytes) >+ pub unsafe fn pa_stream_peek( >+ p: *mut pa_stream, >+ data: *mut *const c_void, >+ nbytes: *mut usize, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, *mut *const c_void, *mut usize) -> c_int, >+ >(PA_STREAM_PEEK))(p, data, nbytes) > } > > static mut PA_STREAM_READABLE_SIZE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_readable_size(p: *const pa_stream) -> usize { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> usize>(PA_STREAM_READABLE_SIZE))(p) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> usize>( >+ PA_STREAM_READABLE_SIZE, >+ ))(p) > } > > static mut PA_STREAM_SET_STATE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_set_state_callback(s: *mut pa_stream, cb: pa_stream_notify_cb_t, userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- pa_stream_notify_cb_t, >- *mut c_void)>(PA_STREAM_SET_STATE_CALLBACK))(s, cb, userdata) >+ pub unsafe fn pa_stream_set_state_callback( >+ s: *mut pa_stream, >+ cb: pa_stream_notify_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, pa_stream_notify_cb_t, *mut c_void), >+ >(PA_STREAM_SET_STATE_CALLBACK))(s, cb, userdata) > } > > static mut PA_STREAM_SET_WRITE_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_set_write_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- pa_stream_request_cb_t, >- *mut c_void)>(PA_STREAM_SET_WRITE_CALLBACK))(p, cb, userdata) >+ pub unsafe fn pa_stream_set_write_callback( >+ p: *mut pa_stream, >+ cb: pa_stream_request_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, pa_stream_request_cb_t, *mut c_void), >+ >(PA_STREAM_SET_WRITE_CALLBACK))(p, cb, userdata) > } > > static mut PA_STREAM_SET_READ_CALLBACK: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_set_read_callback(p: *mut pa_stream, cb: pa_stream_request_cb_t, userdata: *mut c_void) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- pa_stream_request_cb_t, >- *mut c_void)>(PA_STREAM_SET_READ_CALLBACK))(p, cb, userdata) >+ pub unsafe fn pa_stream_set_read_callback( >+ p: *mut pa_stream, >+ cb: pa_stream_request_cb_t, >+ userdata: *mut c_void, >+ ) { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, pa_stream_request_cb_t, *mut c_void), >+ >(PA_STREAM_SET_READ_CALLBACK))(p, cb, userdata) > } > > static mut PA_STREAM_REF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_ref(s: *mut pa_stream) -> *mut pa_stream { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> *mut pa_stream>(PA_STREAM_REF))(s) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream) -> *mut pa_stream>(PA_STREAM_REF))( >+ s, >+ ) > } > > static mut PA_STREAM_UNREF: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_unref(s: *mut pa_stream) { > (::std::mem::transmute::<_, extern "C" fn(*mut pa_stream)>(PA_STREAM_UNREF))(s) > } > > static mut PA_STREAM_UPDATE_TIMING_INFO: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_update_timing_info(p: *mut pa_stream, >- cb: pa_stream_success_cb_t, >- userdata: *mut c_void) >- -> *mut pa_operation { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, pa_stream_success_cb_t, *mut c_void) >- -> *mut pa_operation>(PA_STREAM_UPDATE_TIMING_INFO))(p, cb, userdata) >+ pub unsafe fn pa_stream_update_timing_info( >+ p: *mut pa_stream, >+ cb: pa_stream_success_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_operation { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, pa_stream_success_cb_t, *mut c_void) -> *mut pa_operation, >+ >(PA_STREAM_UPDATE_TIMING_INFO))(p, cb, userdata) > } > > static mut PA_STREAM_WRITABLE_SIZE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_stream_writable_size(p: *const pa_stream) -> usize { >- (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> usize>(PA_STREAM_WRITABLE_SIZE))(p) >+ (::std::mem::transmute::<_, extern "C" fn(*const pa_stream) -> usize>( >+ PA_STREAM_WRITABLE_SIZE, >+ ))(p) > } > > static mut PA_STREAM_WRITE: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_stream_write(p: *mut pa_stream, >- data: *const c_void, >- nbytes: usize, >- free_cb: pa_free_cb_t, >- offset: i64, >- seek: pa_seek_mode_t) >- -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_stream, >- *const c_void, >- usize, >- pa_free_cb_t, >- i64, >- pa_seek_mode_t) >- -> c_int>(PA_STREAM_WRITE))(p, data, nbytes, free_cb, offset, seek) >+ pub unsafe fn pa_stream_write( >+ p: *mut pa_stream, >+ data: *const c_void, >+ nbytes: usize, >+ free_cb: pa_free_cb_t, >+ offset: i64, >+ seek: pa_seek_mode_t, >+ ) -> c_int { >+ (::std::mem::transmute::< >+ _, >+ extern "C" fn(*mut pa_stream, *const c_void, usize, pa_free_cb_t, i64, pa_seek_mode_t) >+ -> c_int, >+ >(PA_STREAM_WRITE))(p, data, nbytes, free_cb, offset, seek) > } > > static mut PA_SW_VOLUME_FROM_LINEAR: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_sw_volume_from_linear(v: c_double) -> pa_volume_t { >- (::std::mem::transmute::<_, extern "C" fn(c_double) -> pa_volume_t>(PA_SW_VOLUME_FROM_LINEAR))(v) >+ (::std::mem::transmute::<_, extern "C" fn(c_double) -> pa_volume_t>( >+ PA_SW_VOLUME_FROM_LINEAR, >+ ))(v) > } > > static mut PA_THREADED_MAINLOOP_FREE: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_free(m: *mut pa_threaded_mainloop) { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>(PA_THREADED_MAINLOOP_FREE))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>( >+ PA_THREADED_MAINLOOP_FREE, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_GET_API: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_threaded_mainloop_get_api(m: *mut pa_threaded_mainloop) -> *mut pa_mainloop_api { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_threaded_mainloop) >- -> *mut pa_mainloop_api>(PA_THREADED_MAINLOOP_GET_API))(m) >+ pub unsafe fn pa_threaded_mainloop_get_api( >+ m: *mut pa_threaded_mainloop, >+ ) -> *mut pa_mainloop_api { >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop) -> *mut pa_mainloop_api>( >+ PA_THREADED_MAINLOOP_GET_API, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_IN_THREAD: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_in_thread(m: *mut pa_threaded_mainloop) -> c_int { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_threaded_mainloop) >- -> c_int>(PA_THREADED_MAINLOOP_IN_THREAD))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop) -> c_int>( >+ PA_THREADED_MAINLOOP_IN_THREAD, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_LOCK: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_lock(m: *mut pa_threaded_mainloop) { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>(PA_THREADED_MAINLOOP_LOCK))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>( >+ PA_THREADED_MAINLOOP_LOCK, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_NEW: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_new() -> *mut pa_threaded_mainloop { >- (::std::mem::transmute::<_, extern "C" fn() -> *mut pa_threaded_mainloop>(PA_THREADED_MAINLOOP_NEW))() >+ (::std::mem::transmute::<_, extern "C" fn() -> *mut pa_threaded_mainloop>( >+ PA_THREADED_MAINLOOP_NEW, >+ ))() > } > > static mut PA_THREADED_MAINLOOP_SIGNAL: *mut ::libc::c_void = 0 as *mut _; > #[inline] >- pub unsafe fn pa_threaded_mainloop_signal(m: *mut pa_threaded_mainloop, wait_for_accept: c_int) { >- (::std::mem::transmute::<_, >- extern "C" fn(*mut pa_threaded_mainloop, >- c_int)>(PA_THREADED_MAINLOOP_SIGNAL))(m, wait_for_accept) >+ pub unsafe fn pa_threaded_mainloop_signal( >+ m: *mut pa_threaded_mainloop, >+ wait_for_accept: c_int, >+ ) { >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop, c_int)>( >+ PA_THREADED_MAINLOOP_SIGNAL, >+ ))(m, wait_for_accept) > } > > static mut PA_THREADED_MAINLOOP_START: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_start(m: *mut pa_threaded_mainloop) -> c_int { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop) -> c_int>(PA_THREADED_MAINLOOP_START))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop) -> c_int>( >+ PA_THREADED_MAINLOOP_START, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_STOP: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_stop(m: *mut pa_threaded_mainloop) { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>(PA_THREADED_MAINLOOP_STOP))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>( >+ PA_THREADED_MAINLOOP_STOP, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_UNLOCK: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_unlock(m: *mut pa_threaded_mainloop) { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>(PA_THREADED_MAINLOOP_UNLOCK))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>( >+ PA_THREADED_MAINLOOP_UNLOCK, >+ ))(m) > } > > static mut PA_THREADED_MAINLOOP_WAIT: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_threaded_mainloop_wait(m: *mut pa_threaded_mainloop) { >- (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>(PA_THREADED_MAINLOOP_WAIT))(m) >+ (::std::mem::transmute::<_, extern "C" fn(*mut pa_threaded_mainloop)>( >+ PA_THREADED_MAINLOOP_WAIT, >+ ))(m) > } > > static mut PA_USEC_TO_BYTES: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_usec_to_bytes(t: pa_usec_t, spec: *const pa_sample_spec) -> usize { >- (::std::mem::transmute::<_, extern "C" fn(pa_usec_t, *const pa_sample_spec) -> usize>(PA_USEC_TO_BYTES))(t, >- spec) >+ (::std::mem::transmute::<_, extern "C" fn(pa_usec_t, *const pa_sample_spec) -> usize>( >+ PA_USEC_TO_BYTES, >+ ))(t, spec) > } > > static mut PA_XREALLOC: *mut ::libc::c_void = 0 as *mut _; > #[inline] > pub unsafe fn pa_xrealloc(ptr: *mut c_void, size: usize) -> *mut c_void { >- (::std::mem::transmute::<_, extern "C" fn(*mut c_void, usize) -> *mut c_void>(PA_XREALLOC))(ptr, size) >+ (::std::mem::transmute::<_, extern "C" fn(*mut c_void, usize) -> *mut c_void>(PA_XREALLOC))( >+ ptr, size, >+ ) > } > > } > > #[cfg(feature = "dlopen")] > pub use self::dynamic_fns::*; >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs >index 0bfad62bca7e..baf6920e467c 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/ffi_types.rs >@@ -49,17 +49,20 @@ pub const PA_CONTEXT_AUTHORIZING: c_int = 2; > pub const PA_CONTEXT_SETTING_NAME: c_int = 3; > pub const PA_CONTEXT_READY: c_int = 4; > pub const PA_CONTEXT_FAILED: c_int = 5; > pub const PA_CONTEXT_TERMINATED: c_int = 6; > pub type pa_context_state_t = c_int; > > #[allow(non_snake_case)] > pub fn PA_CONTEXT_IS_GOOD(x: pa_context_state_t) -> bool { >- x == PA_CONTEXT_CONNECTING || x == PA_CONTEXT_AUTHORIZING || x == PA_CONTEXT_SETTING_NAME || x == PA_CONTEXT_READY >+ x == PA_CONTEXT_CONNECTING >+ || x == PA_CONTEXT_AUTHORIZING >+ || x == PA_CONTEXT_SETTING_NAME >+ || x == PA_CONTEXT_READY > } > > pub const PA_STREAM_UNCONNECTED: c_int = 0; > pub const PA_STREAM_CREATING: c_int = 1; > pub const PA_STREAM_READY: c_int = 2; > pub const PA_STREAM_FAILED: c_int = 3; > pub const PA_STREAM_TERMINATED: c_int = 4; > pub type pa_stream_state_t = c_int; >@@ -292,85 +295,103 @@ pub type pa_port_available_t = c_int; > > pub const PA_IO_EVENT_NULL: c_int = 0; > pub const PA_IO_EVENT_INPUT: c_int = 1; > pub const PA_IO_EVENT_OUTPUT: c_int = 2; > pub const PA_IO_EVENT_HANGUP: c_int = 4; > pub const PA_IO_EVENT_ERROR: c_int = 8; > pub type pa_io_event_flags_t = c_int; > >-pub enum pa_io_event { } >-pub type pa_io_event_cb_t = Option<unsafe extern "C" fn(ea: *mut pa_mainloop_api, >- e: *mut pa_io_event, >- fd: c_int, >- events: pa_io_event_flags_t, >- userdata: *mut c_void)>; >-pub type pa_io_event_destroy_cb_t = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- e: *mut pa_io_event, >- userdata: *mut c_void)>; >-pub enum pa_time_event { } >-pub type pa_time_event_cb_t = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- e: *mut pa_time_event, >- tv: *const timeval, >- userdata: *mut c_void)>; >-pub type pa_time_event_destroy_cb_t = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- e: *mut pa_time_event, >- userdata: *mut c_void)>; >+pub enum pa_io_event {} >+pub type pa_io_event_cb_t = Option< >+ unsafe extern "C" fn( >+ ea: *mut pa_mainloop_api, >+ e: *mut pa_io_event, >+ fd: c_int, >+ events: pa_io_event_flags_t, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_io_event_destroy_cb_t = Option< >+ unsafe extern "C" fn(a: *mut pa_mainloop_api, e: *mut pa_io_event, userdata: *mut c_void), >+>; >+pub enum pa_time_event {} >+pub type pa_time_event_cb_t = Option< >+ unsafe extern "C" fn( >+ a: *mut pa_mainloop_api, >+ e: *mut pa_time_event, >+ tv: *const timeval, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_time_event_destroy_cb_t = Option< >+ unsafe extern "C" fn(a: *mut pa_mainloop_api, e: *mut pa_time_event, userdata: *mut c_void), >+>; > >-pub enum pa_defer_event { } >-pub type pa_defer_event_cb_t = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- e: *mut pa_defer_event, >- userdata: *mut c_void)>; >-pub type pa_defer_event_destroy_cb_t = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- e: *mut pa_defer_event, >- userdata: *mut c_void)>; >-pub type IoNewFn = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- fd: c_int, >- events: pa_io_event_flags_t, >- cb: pa_io_event_cb_t, >- userdata: *mut c_void) >- -> *mut pa_io_event>; >-pub type TimeNewFn = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- tv: *const timeval, >- cb: pa_time_event_cb_t, >- userdata: *mut c_void) >- -> *mut pa_time_event>; >-pub type DeferNewFn = Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, >- cb: pa_defer_event_cb_t, >- userdata: *mut c_void) >- -> *mut pa_defer_event>; >+pub enum pa_defer_event {} >+pub type pa_defer_event_cb_t = Option< >+ unsafe extern "C" fn(a: *mut pa_mainloop_api, e: *mut pa_defer_event, userdata: *mut c_void), >+>; >+pub type pa_defer_event_destroy_cb_t = Option< >+ unsafe extern "C" fn(a: *mut pa_mainloop_api, e: *mut pa_defer_event, userdata: *mut c_void), >+>; >+pub type IoNewFn = Option< >+ unsafe extern "C" fn( >+ a: *mut pa_mainloop_api, >+ fd: c_int, >+ events: pa_io_event_flags_t, >+ cb: pa_io_event_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_io_event, >+>; >+pub type TimeNewFn = Option< >+ unsafe extern "C" fn( >+ a: *mut pa_mainloop_api, >+ tv: *const timeval, >+ cb: pa_time_event_cb_t, >+ userdata: *mut c_void, >+ ) -> *mut pa_time_event, >+>; >+pub type DeferNewFn = Option< >+ unsafe extern "C" fn(a: *mut pa_mainloop_api, cb: pa_defer_event_cb_t, userdata: *mut c_void) >+ -> *mut pa_defer_event, >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_mainloop_api { > pub userdata: *mut c_void, > pub io_new: IoNewFn, > pub io_enable: Option<unsafe extern "C" fn(e: *mut pa_io_event, events: pa_io_event_flags_t)>, > pub io_free: Option<unsafe extern "C" fn(e: *mut pa_io_event)>, >- pub io_set_destroy: Option<unsafe extern "C" fn(e: *mut pa_io_event, cb: pa_io_event_destroy_cb_t)>, >+ pub io_set_destroy: >+ Option<unsafe extern "C" fn(e: *mut pa_io_event, cb: pa_io_event_destroy_cb_t)>, > pub time_new: TimeNewFn, > pub time_restart: Option<unsafe extern "C" fn(e: *mut pa_time_event, tv: *const timeval)>, > pub time_free: Option<unsafe extern "C" fn(e: *mut pa_time_event)>, >- pub time_set_destroy: Option<unsafe extern "C" fn(e: *mut pa_time_event, cb: pa_time_event_destroy_cb_t)>, >+ pub time_set_destroy: >+ Option<unsafe extern "C" fn(e: *mut pa_time_event, cb: pa_time_event_destroy_cb_t)>, > pub defer_new: DeferNewFn, > pub defer_enable: Option<unsafe extern "C" fn(e: *mut pa_defer_event, b: c_int)>, > pub defer_free: Option<unsafe extern "C" fn(e: *mut pa_defer_event)>, >- pub defer_set_destroy: Option<unsafe extern "C" fn(e: *mut pa_defer_event, cb: pa_defer_event_destroy_cb_t)>, >+ pub defer_set_destroy: >+ Option<unsafe extern "C" fn(e: *mut pa_defer_event, cb: pa_defer_event_destroy_cb_t)>, > pub quit: Option<unsafe extern "C" fn(a: *mut pa_mainloop_api, retval: c_int)>, > } > > impl ::std::default::Default for pa_mainloop_api { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_mainloop_api_once_cb_t = Option<unsafe extern "C" fn(m: *mut pa_mainloop_api, userdata: *mut c_void)>; >+pub type pa_mainloop_api_once_cb_t = >+ Option<unsafe extern "C" fn(m: *mut pa_mainloop_api, userdata: *mut c_void)>; > >-pub enum pa_proplist { } >+pub enum pa_proplist {} > > pub const PA_UPDATE_SET: c_int = 0; > pub const PA_UPDATE_MERGE: c_int = 1; > pub const PA_UPDATE_REPLACE: c_int = 2; > pub type pa_update_mode_t = c_int; > > pub const PA_CHANNEL_POSITION_INVALID: c_int = -1; > pub const PA_CHANNEL_POSITION_MONO: c_int = 0; >@@ -481,54 +502,64 @@ impl ::std::default::Default for pa_format_info { > pub const PA_PROP_TYPE_INT: c_int = 0; > pub const PA_PROP_TYPE_INT_RANGE: c_int = 1; > pub const PA_PROP_TYPE_INT_ARRAY: c_int = 2; > pub const PA_PROP_TYPE_STRING: c_int = 3; > pub const PA_PROP_TYPE_STRING_ARRAY: c_int = 4; > pub const PA_PROP_TYPE_INVALID: c_int = -1; > pub type pa_prop_type_t = c_int; > >-pub enum pa_operation { } >-pub type pa_operation_notify_cb_t = Option<unsafe extern "C" fn(o: *mut pa_operation, userdata: *mut c_void)>; >+pub enum pa_operation {} >+pub type pa_operation_notify_cb_t = >+ Option<unsafe extern "C" fn(o: *mut pa_operation, userdata: *mut c_void)>; > >-pub enum pa_context { } >-pub type pa_context_notify_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, userdata: *mut c_void)>; >-pub type pa_context_success_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- success: c_int, >- userdata: *mut c_void)>; >-pub type pa_context_event_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- name: *const c_char, >- p: *mut pa_proplist, >- userdata: *mut c_void)>; >+pub enum pa_context {} >+pub type pa_context_notify_cb_t = >+ Option<unsafe extern "C" fn(c: *mut pa_context, userdata: *mut c_void)>; >+pub type pa_context_success_cb_t = >+ Option<unsafe extern "C" fn(c: *mut pa_context, success: c_int, userdata: *mut c_void)>; >+pub type pa_context_event_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ name: *const c_char, >+ p: *mut pa_proplist, >+ userdata: *mut c_void, >+ ), >+>; > > pub type pa_volume_t = u32; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_cvolume { > pub channels: u8, > pub values: [pa_volume_t; 32usize], > } > > impl ::std::default::Default for pa_cvolume { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub enum pa_stream { } >-pub type pa_stream_success_cb_t = Option<unsafe extern "C" fn(s: *mut pa_stream, >- success: c_int, >- userdata: *mut c_void)>; >-pub type pa_stream_request_cb_t = Option<unsafe extern "C" fn(p: *mut pa_stream, nbytes: usize, userdata: *mut c_void)>; >-pub type pa_stream_notify_cb_t = Option<unsafe extern "C" fn(p: *mut pa_stream, userdata: *mut c_void)>; >-pub type pa_stream_event_cb_t = Option<unsafe extern "C" fn(p: *mut pa_stream, >- name: *const c_char, >- pl: *mut pa_proplist, >- userdata: *mut c_void)>; >+pub enum pa_stream {} >+pub type pa_stream_success_cb_t = >+ Option<unsafe extern "C" fn(s: *mut pa_stream, success: c_int, userdata: *mut c_void)>; >+pub type pa_stream_request_cb_t = >+ Option<unsafe extern "C" fn(p: *mut pa_stream, nbytes: usize, userdata: *mut c_void)>; >+pub type pa_stream_notify_cb_t = >+ Option<unsafe extern "C" fn(p: *mut pa_stream, userdata: *mut c_void)>; >+pub type pa_stream_event_cb_t = Option< >+ unsafe extern "C" fn( >+ p: *mut pa_stream, >+ name: *const c_char, >+ pl: *mut pa_proplist, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_port_info { > pub name: *const c_char, > pub description: *const c_char, > pub priority: u32, > pub available: c_int, >@@ -570,20 +601,24 @@ pub struct pa_sink_info { > } > > impl ::std::default::Default for pa_sink_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_sink_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_sink_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_sink_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_sink_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_source_info { > pub name: *const c_char, > pub index: u32, > pub description: *const c_char, > pub sample_spec: pa_sample_spec, >@@ -610,20 +645,24 @@ pub struct pa_source_info { > } > > impl ::std::default::Default for pa_source_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_source_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_source_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_source_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_source_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_server_info { > pub user_name: *const c_char, > pub host_name: *const c_char, > pub server_version: *const c_char, > pub server_name: *const c_char, >@@ -635,19 +674,19 @@ pub struct pa_server_info { > } > > impl ::std::default::Default for pa_server_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_server_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_server_info, >- userdata: *mut c_void)>; >+pub type pa_server_info_cb_t = Option< >+ unsafe extern "C" fn(c: *mut pa_context, i: *const pa_server_info, userdata: *mut c_void), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_module_info { > pub index: u32, > pub name: *const c_char, > pub argument: *const c_char, > pub n_used: u32, >@@ -656,21 +695,26 @@ pub struct pa_module_info { > } > > impl ::std::default::Default for pa_module_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_module_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_module_info, >- eol: c_int, >- userdata: *mut c_void)>; >-pub type pa_context_index_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, idx: u32, userdata: *mut c_void)>; >+pub type pa_module_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_module_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_context_index_cb_t = >+ Option<unsafe extern "C" fn(c: *mut pa_context, idx: u32, userdata: *mut c_void)>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_client_info { > pub index: u32, > pub name: *const c_char, > pub owner_module: u32, > pub driver: *const c_char, >@@ -678,20 +722,24 @@ pub struct pa_client_info { > } > > impl ::std::default::Default for pa_client_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_client_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_client_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_client_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_client_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_card_profile_info { > pub name: *const c_char, > pub description: *const c_char, > pub n_sinks: u32, > pub n_sources: u32, >@@ -760,20 +808,24 @@ pub struct pa_card_info { > } > > impl ::std::default::Default for pa_card_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_card_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_card_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_card_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_card_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_sink_input_info { > pub index: u32, > pub name: *const c_char, > pub owner_module: u32, > pub client: u32, >@@ -794,20 +846,24 @@ pub struct pa_sink_input_info { > } > > impl ::std::default::Default for pa_sink_input_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_sink_input_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_sink_input_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_sink_input_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_sink_input_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_source_output_info { > pub index: u32, > pub name: *const c_char, > pub owner_module: u32, > pub client: u32, >@@ -828,20 +884,24 @@ pub struct pa_source_output_info { > } > > impl ::std::default::Default for pa_source_output_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_source_output_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_source_output_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_source_output_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_source_output_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_stat_info { > pub memblock_total: u32, > pub memblock_total_size: u32, > pub memblock_allocated: u32, > pub memblock_allocated_size: u32, >@@ -849,19 +909,18 @@ pub struct pa_stat_info { > } > > impl ::std::default::Default for pa_stat_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_stat_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_stat_info, >- userdata: *mut c_void)>; >+pub type pa_stat_info_cb_t = >+ Option<unsafe extern "C" fn(c: *mut pa_context, i: *const pa_stat_info, userdata: *mut c_void)>; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_sample_info { > pub index: u32, > pub name: *const c_char, > pub volume: pa_cvolume, > pub sample_spec: pa_sample_spec, >@@ -874,20 +933,24 @@ pub struct pa_sample_info { > } > > impl ::std::default::Default for pa_sample_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_sample_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_sample_info, >- eol: c_int, >- userdata: *mut c_void)>; >+pub type pa_sample_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_sample_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; > > pub const PA_AUTOLOAD_SINK: c_int = 0; > pub const PA_AUTOLOAD_SOURCE: c_int = 1; > pub type pa_autoload_type_t = c_int; > > #[repr(C)] > #[derive(Clone, Copy, Debug)] > pub struct pa_autoload_info { >@@ -899,38 +962,48 @@ pub struct pa_autoload_info { > } > > impl ::std::default::Default for pa_autoload_info { > fn default() -> Self { > unsafe { ::std::mem::zeroed() } > } > } > >-pub type pa_autoload_info_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- i: *const pa_autoload_info, >- eol: c_int, >- userdata: *mut c_void)>; >-pub type pa_context_subscribe_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- t: pa_subscription_event_type_t, >- idx: u32, >- userdata: *mut c_void)>; >-pub type pa_context_play_sample_cb_t = Option<unsafe extern "C" fn(c: *mut pa_context, >- idx: u32, >- userdata: *mut c_void)>; >+pub type pa_autoload_info_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ i: *const pa_autoload_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_context_subscribe_cb_t = Option< >+ unsafe extern "C" fn( >+ c: *mut pa_context, >+ t: pa_subscription_event_type_t, >+ idx: u32, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_context_play_sample_cb_t = >+ Option<unsafe extern "C" fn(c: *mut pa_context, idx: u32, userdata: *mut c_void)>; > >-pub enum pa_threaded_mainloop { } >-pub enum pollfd { } >-pub enum pa_mainloop { } >+pub enum pa_threaded_mainloop {} >+pub enum pollfd {} >+pub enum pa_mainloop {} > >-pub type pa_poll_func = Option<unsafe extern "C" fn(ufds: *mut pollfd, >- nfds: c_ulong, >- timeout: c_int, >- userdata: *mut c_void) >- -> c_int>; >-pub enum pa_signal_event { } >+pub type pa_poll_func = Option< >+ unsafe extern "C" fn(ufds: *mut pollfd, nfds: c_ulong, timeout: c_int, userdata: *mut c_void) >+ -> c_int, >+>; >+pub enum pa_signal_event {} > >-pub type pa_signal_cb_t = Option<unsafe extern "C" fn(api: *mut pa_mainloop_api, >- e: *mut pa_signal_event, >- sig: c_int, >- userdata: *mut c_void)>; >-pub type pa_signal_destroy_cb_t = Option<unsafe extern "C" fn(api: *mut pa_mainloop_api, >- e: *mut pa_signal_event, >- userdata: *mut c_void)>; >+pub type pa_signal_cb_t = Option< >+ unsafe extern "C" fn( >+ api: *mut pa_mainloop_api, >+ e: *mut pa_signal_event, >+ sig: c_int, >+ userdata: *mut c_void, >+ ), >+>; >+pub type pa_signal_destroy_cb_t = Option< >+ unsafe extern "C" fn(api: *mut pa_mainloop_api, e: *mut pa_signal_event, userdata: *mut c_void), >+>; >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/lib.rs b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/lib.rs >index a74152e3fc10..3264db62b7e4 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/lib.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-ffi/src/lib.rs >@@ -1,14 +1,14 @@ > // Required for dlopen, et al. > #[cfg(feature = "dlopen")] > extern crate libc; > >-mod ffi_types; > mod ffi_funcs; >+mod ffi_types; > >-pub use ffi_types::*; > pub use ffi_funcs::*; >+pub use ffi_types::*; > > #[cfg(feature = "dlopen")] > pub unsafe fn open() -> Option<LibLoader> { > return LibLoader::open(); > } >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs >index c9b8a3a9609c..5b9b4a432083 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/context.rs >@@ -1,19 +1,19 @@ > // Copyright © 2017 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > >-use ::*; > use ffi; > use std::ffi::CStr; > use std::os::raw::{c_int, c_void}; > use std::ptr; > use util::UnwrapCStr; >+use *; > > // A note about `wrapped` functions > // > // C FFI demands `unsafe extern fn(*mut pa_context, ...) -> i32`, etc, > // but we want to allow such callbacks to be safe. This means no > // `unsafe` or `extern`, and callbacks should be called with a safe > // wrapper of `*mut pa_context`. Since the callback doesn't take > // ownership, this is `&Context`. `fn wrapped<T>(...)` defines a >@@ -51,26 +51,27 @@ use util::UnwrapCStr; > macro_rules! op_or_err { > ($self_:ident, $e:expr) => {{ > let o = unsafe { $e }; > if o.is_null() { > Err(ErrorCode::from_error_code($self_.errno())) > } else { > Ok(unsafe { operation::from_raw_ptr(o) }) > } >- }} >+ }}; > } > > #[repr(C)] > #[derive(Debug)] > pub struct Context(*mut ffi::pa_context); > > impl Context { > pub fn new<'a, OPT>(api: &MainloopApi, name: OPT) -> Option<Self> >- where OPT: Into<Option<&'a CStr>> >+ where >+ OPT: Into<Option<&'a CStr>>, > { > let ptr = unsafe { ffi::pa_context_new(api.raw_mut(), name.unwrap_cstr()) }; > if ptr.is_null() { > None > } else { > Some(Context(ptr)) > } > } >@@ -88,23 +89,25 @@ impl Context { > > pub fn clear_state_callback(&self) { > unsafe { > ffi::pa_context_set_state_callback(self.raw_mut(), None, ptr::null_mut()); > } > } > > pub fn set_state_callback<CB>(&self, _: CB, userdata: *mut c_void) >- where CB: Fn(&Context, *mut c_void) >+ where >+ CB: Fn(&Context, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions > unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, userdata: *mut c_void) >- where F: Fn(&Context, *mut c_void) >+ where >+ F: Fn(&Context, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, userdata); > forget(ctx); > > result > } >@@ -114,281 +117,362 @@ impl Context { > } > } > > pub fn errno(&self) -> ffi::pa_error_code_t { > unsafe { ffi::pa_context_errno(self.raw_mut()) } > } > > pub fn get_state(&self) -> ContextState { >- ContextState::try_from(unsafe { >- ffi::pa_context_get_state(self.raw_mut()) >- }).expect("pa_context_get_state returned invalid ContextState") >+ ContextState::try_from(unsafe { ffi::pa_context_get_state(self.raw_mut()) }) >+ .expect("pa_context_get_state returned invalid ContextState") > } > >- pub fn connect<'a, OPT>(&self, server: OPT, flags: ContextFlags, api: *const ffi::pa_spawn_api) -> Result<()> >- where OPT: Into<Option<&'a CStr>> >+ pub fn connect<'a, OPT>( >+ &self, >+ server: OPT, >+ flags: ContextFlags, >+ api: *const ffi::pa_spawn_api, >+ ) -> Result<()> >+ where >+ OPT: Into<Option<&'a CStr>>, > { > let r = unsafe { >- ffi::pa_context_connect(self.raw_mut(), >- server.into().unwrap_cstr(), >- flags.into(), >- api) >+ ffi::pa_context_connect( >+ self.raw_mut(), >+ server.into().unwrap_cstr(), >+ flags.into(), >+ api, >+ ) > }; > error_result!((), r) > } > > pub fn disconnect(&self) { > unsafe { > ffi::pa_context_disconnect(self.raw_mut()); > } > } > >- > pub fn drain<CB>(&self, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, *mut c_void) >+ where >+ CB: Fn(&Context, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions > unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, userdata: *mut c_void) >- where F: Fn(&Context, *mut c_void) >+ where >+ F: Fn(&Context, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_drain(self.raw_mut(), Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_drain(self.raw_mut(), Some(wrapped::<CB>), userdata) >+ ) > } > >- pub fn rttime_new<CB>(&self, usec: USec, _: CB, userdata: *mut c_void) -> *mut ffi::pa_time_event >- where CB: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void) >+ pub fn rttime_new<CB>( >+ &self, >+ usec: USec, >+ _: CB, >+ userdata: *mut c_void, >+ ) -> *mut ffi::pa_time_event >+ where >+ CB: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(a: *mut ffi::pa_mainloop_api, >- e: *mut ffi::pa_time_event, >- tv: *const TimeVal, >- userdata: *mut c_void) >- where F: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ a: *mut ffi::pa_mainloop_api, >+ e: *mut ffi::pa_time_event, >+ tv: *const TimeVal, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&MainloopApi, *mut ffi::pa_time_event, &TimeVal, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let api = mainloop_api::from_raw_ptr(a); > let timeval = &*tv; > let result = uninitialized::<F>()(&api, e, timeval, userdata); > forget(api); > > result > } > > unsafe { ffi::pa_context_rttime_new(self.raw_mut(), usec, Some(wrapped::<CB>), userdata) } > } > > pub fn get_server_info<CB>(&self, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, Option<&ServerInfo>, *mut c_void) >+ where >+ CB: Fn(&Context, Option<&ServerInfo>, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, i: *const ffi::pa_server_info, userdata: *mut c_void) >- where F: Fn(&Context, Option<&ServerInfo>, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ i: *const ffi::pa_server_info, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, Option<&ServerInfo>, *mut c_void), > { > use std::mem::{forget, uninitialized}; >- let info = if i.is_null() { >- None >- } else { >- Some(&*i) >- }; >+ let info = if i.is_null() { None } else { Some(&*i) }; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, info, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_get_server_info(self.raw_mut(), Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_get_server_info(self.raw_mut(), Some(wrapped::<CB>), userdata) >+ ) > } > >- pub fn get_sink_info_by_name<'str, CS, CB>(&self, name: CS, _: CB, userdata: *mut c_void) -> Result<Operation> >+ pub fn get_sink_info_by_name<'str, CS, CB>( >+ &self, >+ name: CS, >+ _: CB, >+ userdata: *mut c_void, >+ ) -> Result<Operation> > where > CB: Fn(&Context, *const SinkInfo, i32, *mut c_void), > CS: Into<Option<&'str CStr>>, > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, >- info: *const ffi::pa_sink_info, >- eol: c_int, >- userdata: *mut c_void) >- where F: Fn(&Context, *const SinkInfo, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ info: *const ffi::pa_sink_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, *const SinkInfo, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, info, eol, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_get_sink_info_by_name(self.raw_mut(), >- name.into().unwrap_cstr(), >- Some(wrapped::<CB>), >- userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_get_sink_info_by_name( >+ self.raw_mut(), >+ name.into().unwrap_cstr(), >+ Some(wrapped::<CB>), >+ userdata >+ ) >+ ) > } > > pub fn get_sink_info_list<CB>(&self, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, *const SinkInfo, i32, *mut c_void) >+ where >+ CB: Fn(&Context, *const SinkInfo, i32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, >- info: *const ffi::pa_sink_info, >- eol: c_int, >- userdata: *mut c_void) >- where F: Fn(&Context, *const SinkInfo, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ info: *const ffi::pa_sink_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, *const SinkInfo, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, info, eol, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_get_sink_info_list(self.raw_mut(), Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_get_sink_info_list(self.raw_mut(), Some(wrapped::<CB>), userdata) >+ ) > } > >- pub fn get_sink_input_info<CB>(&self, idx: u32, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, *const SinkInputInfo, i32, *mut c_void) >+ pub fn get_sink_input_info<CB>( >+ &self, >+ idx: u32, >+ _: CB, >+ userdata: *mut c_void, >+ ) -> Result<Operation> >+ where >+ CB: Fn(&Context, *const SinkInputInfo, i32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, >- info: *const ffi::pa_sink_input_info, >- eol: c_int, >- userdata: *mut c_void) >- where F: Fn(&Context, *const SinkInputInfo, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ info: *const ffi::pa_sink_input_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, *const SinkInputInfo, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, info, eol, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_get_sink_input_info(self.raw_mut(), idx, Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_get_sink_input_info(self.raw_mut(), idx, Some(wrapped::<CB>), userdata) >+ ) > } > > pub fn get_source_info_list<CB>(&self, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, *const SourceInfo, i32, *mut c_void) >+ where >+ CB: Fn(&Context, *const SourceInfo, i32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, >- info: *const ffi::pa_source_info, >- eol: c_int, >- userdata: *mut c_void) >- where F: Fn(&Context, *const SourceInfo, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ info: *const ffi::pa_source_info, >+ eol: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, *const SourceInfo, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, info, eol, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_get_source_info_list(self.raw_mut(), Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_get_source_info_list(self.raw_mut(), Some(wrapped::<CB>), userdata) >+ ) > } > >- pub fn set_sink_input_volume<CB>(&self, >- idx: u32, >- volume: &CVolume, >- _: CB, >- userdata: *mut c_void) >- -> Result<Operation> >- where CB: Fn(&Context, i32, *mut c_void) >+ pub fn set_sink_input_volume<CB>( >+ &self, >+ idx: u32, >+ volume: &CVolume, >+ _: CB, >+ userdata: *mut c_void, >+ ) -> Result<Operation> >+ where >+ CB: Fn(&Context, i32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, success: c_int, userdata: *mut c_void) >- where F: Fn(&Context, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ success: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, success, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_set_sink_input_volume(self.raw_mut(), idx, volume, Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_set_sink_input_volume( >+ self.raw_mut(), >+ idx, >+ volume, >+ Some(wrapped::<CB>), >+ userdata >+ ) >+ ) > } > >- pub fn subscribe<CB>(&self, m: SubscriptionMask, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Context, i32, *mut c_void) >+ pub fn subscribe<CB>( >+ &self, >+ m: SubscriptionMask, >+ _: CB, >+ userdata: *mut c_void, >+ ) -> Result<Operation> >+ where >+ CB: Fn(&Context, i32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, success: c_int, userdata: *mut c_void) >- where F: Fn(&Context, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ success: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let result = uninitialized::<F>()(&ctx, success, userdata); > forget(ctx); > > result > } > >- op_or_err!(self, >- ffi::pa_context_subscribe(self.raw_mut(), m.into(), Some(wrapped::<CB>), userdata)) >+ op_or_err!( >+ self, >+ ffi::pa_context_subscribe(self.raw_mut(), m.into(), Some(wrapped::<CB>), userdata) >+ ) > } > > pub fn clear_subscribe_callback(&self) { > unsafe { > ffi::pa_context_set_subscribe_callback(self.raw_mut(), None, ptr::null_mut()); > } > } > > pub fn set_subscribe_callback<CB>(&self, _: CB, userdata: *mut c_void) >- where CB: Fn(&Context, SubscriptionEvent, u32, *mut c_void) >+ where >+ CB: Fn(&Context, SubscriptionEvent, u32, *mut c_void), > { > debug_assert_eq!(::std::mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(c: *mut ffi::pa_context, >- t: ffi::pa_subscription_event_type_t, >- idx: u32, >- userdata: *mut c_void) >- where F: Fn(&Context, SubscriptionEvent, u32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ c: *mut ffi::pa_context, >+ t: ffi::pa_subscription_event_type_t, >+ idx: u32, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Context, SubscriptionEvent, u32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let ctx = context::from_raw_ptr(c); > let event = SubscriptionEvent::try_from(t) >- .expect("pa_context_subscribe_cb_t passed invalid pa_subscription_event_type_t"); >+ .expect("pa_context_subscribe_cb_t passed invalid pa_subscription_event_type_t"); > let result = uninitialized::<F>()(&ctx, event, idx, userdata); > forget(ctx); > > result > } > > unsafe { > ffi::pa_context_set_subscribe_callback(self.raw_mut(), Some(wrapped::<CB>), userdata); >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs >index 99deae2b482d..2e6f7074f27a 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/error.rs >@@ -9,17 +9,17 @@ use std::ffi::CStr; > #[macro_export] > macro_rules! error_result { > ($t:expr, $err:expr) => { > if $err >= 0 { > Ok($t) > } else { > Err(ErrorCode::from_error_result($err)) > } >- } >+ }; > } > > #[derive(Debug, PartialEq)] > pub struct ErrorCode { > err: ffi::pa_error_code_t, > } > > impl ErrorCode { >@@ -27,19 +27,17 @@ impl ErrorCode { > debug_assert!(err < 0); > ErrorCode { > err: (-err) as ffi::pa_error_code_t, > } > } > > pub fn from_error_code(err: ffi::pa_error_code_t) -> Self { > debug_assert!(err > 0); >- ErrorCode { >- err: err, >- } >+ ErrorCode { err: err } > } > > fn desc(&self) -> &'static str { > let cstr = unsafe { CStr::from_ptr(ffi::pa_strerror(self.err)) }; > cstr.to_str().unwrap() > } > } > >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs >index f12f0a5bfb35..c852e5907ab2 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/lib.rs >@@ -81,20 +81,20 @@ pub enum ContextState { > Terminated = ffi::PA_CONTEXT_TERMINATED, > } > > impl ContextState { > // This function implements the PA_CONTENT_IS_GOOD macro from pulse/def.h > // It must match the version from PA headers. > pub fn is_good(self) -> bool { > match self { >- ContextState::Connecting | >- ContextState::Authorizing | >- ContextState::SettingName | >- ContextState::Ready => true, >+ ContextState::Connecting >+ | ContextState::Authorizing >+ | ContextState::SettingName >+ | ContextState::Ready => true, > _ => false, > } > } > > pub fn try_from(x: ffi::pa_context_state_t) -> Option<Self> { > if x >= ffi::PA_CONTEXT_UNCONNECTED && x <= ffi::PA_CONTEXT_TERMINATED { > Some(unsafe { ::std::mem::transmute(x) }) > } else { >@@ -211,17 +211,16 @@ impl DeviceType { > } > > impl Into<ffi::pa_device_type_t> for DeviceType { > fn into(self) -> ffi::pa_device_type_t { > self as ffi::pa_device_type_t > } > } > >- > #[repr(i32)] > #[derive(Clone, Copy, Debug, PartialEq, Eq)] > pub enum StreamDirection { > NoDirection = ffi::PA_STREAM_NODIRECTION, > Playback = ffi::PA_STREAM_PLAYBACK, > Record = ffi::PA_STREAM_RECORD, > StreamUpload = ffi::PA_STREAM_UPLOAD, > } >@@ -264,28 +263,39 @@ bitflags! { > const FAIL_ON_SUSPEND = ffi::PA_STREAM_FAIL_ON_SUSPEND; > const RELATIVE_VOLUME = ffi::PA_STREAM_RELATIVE_VOLUME; > const PASSTHROUGH = ffi::PA_STREAM_PASSTHROUGH; > } > } > > impl StreamFlags { > pub fn try_from(x: ffi::pa_stream_flags_t) -> Option<Self> { >- if (x & >- !(ffi::PA_STREAM_NOFLAGS | ffi::PA_STREAM_START_CORKED | ffi::PA_STREAM_INTERPOLATE_TIMING | >- ffi::PA_STREAM_NOT_MONOTONIC | ffi::PA_STREAM_AUTO_TIMING_UPDATE | >- ffi::PA_STREAM_NO_REMAP_CHANNELS | >- ffi::PA_STREAM_NO_REMIX_CHANNELS | ffi::PA_STREAM_FIX_FORMAT | ffi::PA_STREAM_FIX_RATE | >- ffi::PA_STREAM_FIX_CHANNELS | >- ffi::PA_STREAM_DONT_MOVE | ffi::PA_STREAM_VARIABLE_RATE | ffi::PA_STREAM_PEAK_DETECT | >- ffi::PA_STREAM_START_MUTED | ffi::PA_STREAM_ADJUST_LATENCY | >- ffi::PA_STREAM_EARLY_REQUESTS | >- ffi::PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND | >- ffi::PA_STREAM_START_UNMUTED | ffi::PA_STREAM_FAIL_ON_SUSPEND | >- ffi::PA_STREAM_RELATIVE_VOLUME | ffi::PA_STREAM_PASSTHROUGH)) == 0 { >+ if (x & !(ffi::PA_STREAM_NOFLAGS >+ | ffi::PA_STREAM_START_CORKED >+ | ffi::PA_STREAM_INTERPOLATE_TIMING >+ | ffi::PA_STREAM_NOT_MONOTONIC >+ | ffi::PA_STREAM_AUTO_TIMING_UPDATE >+ | ffi::PA_STREAM_NO_REMAP_CHANNELS >+ | ffi::PA_STREAM_NO_REMIX_CHANNELS >+ | ffi::PA_STREAM_FIX_FORMAT >+ | ffi::PA_STREAM_FIX_RATE >+ | ffi::PA_STREAM_FIX_CHANNELS >+ | ffi::PA_STREAM_DONT_MOVE >+ | ffi::PA_STREAM_VARIABLE_RATE >+ | ffi::PA_STREAM_PEAK_DETECT >+ | ffi::PA_STREAM_START_MUTED >+ | ffi::PA_STREAM_ADJUST_LATENCY >+ | ffi::PA_STREAM_EARLY_REQUESTS >+ | ffi::PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND >+ | ffi::PA_STREAM_START_UNMUTED >+ | ffi::PA_STREAM_FAIL_ON_SUSPEND >+ | ffi::PA_STREAM_RELATIVE_VOLUME >+ | ffi::PA_STREAM_PASSTHROUGH)) >+ == 0 >+ { > Some(unsafe { ::std::mem::transmute(x) }) > } else { > None > } > } > } > > impl Into<ffi::pa_stream_flags_t> for StreamFlags { >@@ -353,17 +363,19 @@ pub enum SubscriptionEventType { > Remove, > } > > #[repr(C)] > #[derive(Clone, Copy, Debug, PartialEq, Eq)] > pub struct SubscriptionEvent(ffi::pa_subscription_event_type_t); > impl SubscriptionEvent { > pub fn try_from(x: ffi::pa_subscription_event_type_t) -> Option<Self> { >- if (x & !(ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK | ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK)) == 0 { >+ if (x & !(ffi::PA_SUBSCRIPTION_EVENT_TYPE_MASK | ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK)) >+ == 0 >+ { > Some(SubscriptionEvent(x)) > } else { > None > } > } > > pub fn event_facility(self) -> SubscriptionEventFacility { > unsafe { ::std::mem::transmute(self.0 & ffi::PA_SUBSCRIPTION_EVENT_FACILITY_MASK) } >@@ -410,21 +422,28 @@ bitflags! { > const FLAT_VOLUME = ffi::PA_SINK_FLAT_VOLUME; > const DYNAMIC_LATENCY = ffi::PA_SINK_DYNAMIC_LATENCY; > const SET_FORMATS = ffi::PA_SINK_SET_FORMATS; > } > } > > impl SinkFlags { > pub fn try_from(x: ffi::pa_sink_flags_t) -> Option<SinkFlags> { >- if (x & >- !(ffi::PA_SINK_NOFLAGS | ffi::PA_SINK_HW_VOLUME_CTRL | ffi::PA_SINK_LATENCY | >- ffi::PA_SINK_HARDWARE | ffi::PA_SINK_NETWORK | ffi::PA_SINK_HW_MUTE_CTRL | >- ffi::PA_SINK_DECIBEL_VOLUME | ffi::PA_SINK_DYNAMIC_LATENCY | >- ffi::PA_SINK_FLAT_VOLUME | ffi::PA_SINK_SET_FORMATS)) == 0 { >+ if (x & !(ffi::PA_SINK_NOFLAGS >+ | ffi::PA_SINK_HW_VOLUME_CTRL >+ | ffi::PA_SINK_LATENCY >+ | ffi::PA_SINK_HARDWARE >+ | ffi::PA_SINK_NETWORK >+ | ffi::PA_SINK_HW_MUTE_CTRL >+ | ffi::PA_SINK_DECIBEL_VOLUME >+ | ffi::PA_SINK_DYNAMIC_LATENCY >+ | ffi::PA_SINK_FLAT_VOLUME >+ | ffi::PA_SINK_SET_FORMATS)) >+ == 0 >+ { > Some(unsafe { ::std::mem::transmute(x) }) > } else { > None > } > } > } > > #[repr(i32)] >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs >index 1567cc461f22..4b2ad426c358 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/mainloop_api.rs >@@ -2,27 +2,28 @@ > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > > use ffi; > use std::mem; > use std::os::raw::c_void; > >- > #[allow(non_camel_case_types)] >-type pa_once_cb_t = Option<unsafe extern "C" fn(m: *mut ffi::pa_mainloop_api, >- userdata: *mut c_void)>; >+type pa_once_cb_t = >+ Option<unsafe extern "C" fn(m: *mut ffi::pa_mainloop_api, userdata: *mut c_void)>; > fn wrap_once_cb<F>(_: F) -> pa_once_cb_t >- where F: Fn(&MainloopApi, *mut c_void) >+where >+ F: Fn(&MainloopApi, *mut c_void), > { > assert!(mem::size_of::<F>() == 0); > > unsafe extern "C" fn wrapped<F>(m: *mut ffi::pa_mainloop_api, userdata: *mut c_void) >- where F: Fn(&MainloopApi, *mut c_void) >+ where >+ F: Fn(&MainloopApi, *mut c_void), > { > let api = from_raw_ptr(m); > let result = mem::transmute::<_, &F>(&())(&api, userdata); > mem::forget(api); > result > } > > Some(wrapped::<F>) >@@ -31,17 +32,18 @@ fn wrap_once_cb<F>(_: F) -> pa_once_cb_t > pub struct MainloopApi(*mut ffi::pa_mainloop_api); > > impl MainloopApi { > pub fn raw_mut(&self) -> &mut ffi::pa_mainloop_api { > unsafe { &mut *self.0 } > } > > pub fn once<CB>(&self, cb: CB, userdata: *mut c_void) >- where CB: Fn(&MainloopApi, *mut c_void) >+ where >+ CB: Fn(&MainloopApi, *mut c_void), > { > let wrapped = wrap_once_cb(cb); > unsafe { > ffi::pa_mainloop_api_once(self.raw_mut(), wrapped, userdata); > } > } > > pub fn time_free(&self, e: *mut ffi::pa_time_event) { >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs >index d99410c11c8a..460473f4677d 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/proplist.rs >@@ -6,17 +6,18 @@ > use ffi; > use std::ffi::{CStr, CString}; > > #[derive(Debug)] > pub struct Proplist(*mut ffi::pa_proplist); > > impl Proplist { > pub fn gets<T>(&self, key: T) -> Option<&CStr> >- where T: Into<Vec<u8>> >+ where >+ T: Into<Vec<u8>>, > { > let key = match CString::new(key) { > Ok(k) => k, > _ => return None, > }; > let r = unsafe { ffi::pa_proplist_gets(self.0, key.as_ptr()) }; > if r.is_null() { > None >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs >index 785ee1be485d..068233b2c788 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/stream.rs >@@ -1,35 +1,43 @@ > // Copyright © 2017 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > >-use ::*; > use context; > use ffi; > use operation; > use std::ffi::CStr; > use std::mem; > use std::os::raw::{c_int, c_void}; > use std::ptr; > use util::*; >+use *; > > #[derive(Debug)] > pub struct Stream(*mut ffi::pa_stream); > > impl Stream { >- pub fn new<'a, CM>(c: &Context, name: &::std::ffi::CStr, ss: &SampleSpec, map: CM) -> Option<Self> >- where CM: Into<Option<&'a ChannelMap>> >+ pub fn new<'a, CM>( >+ c: &Context, >+ name: &::std::ffi::CStr, >+ ss: &SampleSpec, >+ map: CM, >+ ) -> Option<Self> >+ where >+ CM: Into<Option<&'a ChannelMap>>, > { > let ptr = unsafe { >- ffi::pa_stream_new(c.raw_mut(), >- name.as_ptr(), >- ss as *const _, >- to_ptr(map.into())) >+ ffi::pa_stream_new( >+ c.raw_mut(), >+ name.as_ptr(), >+ ss as *const _, >+ to_ptr(map.into()), >+ ) > }; > if ptr.is_null() { > None > } else { > Some(Stream(ptr)) > } > } > >@@ -40,19 +48,18 @@ impl Stream { > > pub fn unref(self) { > unsafe { > ffi::pa_stream_unref(self.raw_mut()); > } > } > > pub fn get_state(&self) -> StreamState { >- StreamState::try_from(unsafe { >- ffi::pa_stream_get_state(self.raw_mut()) >- }).expect("pa_stream_get_state returned invalid StreamState") >+ StreamState::try_from(unsafe { ffi::pa_stream_get_state(self.raw_mut()) }) >+ .expect("pa_stream_get_state returned invalid StreamState") > } > > pub fn get_context(&self) -> Option<Context> { > let ptr = unsafe { ffi::pa_stream_get_context(self.raw_mut()) }; > if ptr.is_null() { > return None; > } > >@@ -82,48 +89,55 @@ impl Stream { > error_result!(r != 0, r) > } > > pub fn is_corked(&self) -> Result<bool> { > let r = unsafe { ffi::pa_stream_is_corked(self.raw_mut()) }; > error_result!(r != 0, r) > } > >- pub fn connect_playback<'a, D, A, V, S>(&self, >- dev: D, >- attr: A, >- flags: StreamFlags, >- volume: V, >- sync_stream: S) >- -> Result<()> >- where D: Into<Option<&'a CStr>>, >- A: Into<Option<&'a BufferAttr>>, >- V: Into<Option<&'a CVolume>>, >- S: Into<Option<&'a mut Stream>> >+ pub fn connect_playback<'a, D, A, V, S>( >+ &self, >+ dev: D, >+ attr: A, >+ flags: StreamFlags, >+ volume: V, >+ sync_stream: S, >+ ) -> Result<()> >+ where >+ D: Into<Option<&'a CStr>>, >+ A: Into<Option<&'a BufferAttr>>, >+ V: Into<Option<&'a CVolume>>, >+ S: Into<Option<&'a mut Stream>>, > { > let r = unsafe { >- ffi::pa_stream_connect_playback(self.raw_mut(), >- str_to_ptr(dev.into()), >- to_ptr(attr.into()), >- flags.into(), >- to_ptr(volume.into()), >- map_to_mut_ptr(sync_stream.into(), |p| p.0)) >+ ffi::pa_stream_connect_playback( >+ self.raw_mut(), >+ str_to_ptr(dev.into()), >+ to_ptr(attr.into()), >+ flags.into(), >+ to_ptr(volume.into()), >+ map_to_mut_ptr(sync_stream.into(), |p| p.0), >+ ) > }; > error_result!((), r) > } > > pub fn connect_record<'a, D, A>(&self, dev: D, attr: A, flags: StreamFlags) -> Result<()> >- where D: Into<Option<&'a CStr>>, >- A: Into<Option<&'a BufferAttr>> >+ where >+ D: Into<Option<&'a CStr>>, >+ A: Into<Option<&'a BufferAttr>>, > { > let r = unsafe { >- ffi::pa_stream_connect_record(self.raw_mut(), >- str_to_ptr(dev.into()), >- to_ptr(attr.into()), >- flags.into()) >+ ffi::pa_stream_connect_record( >+ self.raw_mut(), >+ str_to_ptr(dev.into()), >+ to_ptr(attr.into()), >+ flags.into(), >+ ) > }; > error_result!((), r) > } > > pub fn disconnect(&self) -> Result<()> { > let r = unsafe { ffi::pa_stream_disconnect(self.raw_mut()) }; > error_result!((), r) > } >@@ -135,18 +149,26 @@ impl Stream { > error_result!((data, nbytes), r) > } > > pub fn cancel_write(&self) -> Result<()> { > let r = unsafe { ffi::pa_stream_cancel_write(self.raw_mut()) }; > error_result!((), r) > } > >- pub fn write(&self, data: *const c_void, nbytes: usize, offset: i64, seek: SeekMode) -> Result<()> { >- let r = unsafe { ffi::pa_stream_write(self.raw_mut(), data, nbytes, None, offset, seek.into()) }; >+ pub fn write( >+ &self, >+ data: *const c_void, >+ nbytes: usize, >+ offset: i64, >+ seek: SeekMode, >+ ) -> Result<()> { >+ let r = unsafe { >+ ffi::pa_stream_write(self.raw_mut(), data, nbytes, None, offset, seek.into()) >+ }; > error_result!((), r) > } > > pub unsafe fn peek(&self, data: *mut *const c_void, length: *mut usize) -> Result<()> { > let r = ffi::pa_stream_peek(self.raw_mut(), data, length); > error_result!((), r) > } > >@@ -177,33 +199,40 @@ impl Stream { > ffi::PA_ERR_UNKNOWN > }; > return Err(ErrorCode::from_error_code(err)); > } > Ok(r) > } > > pub fn update_timing_info<CB>(&self, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Stream, i32, *mut c_void) >+ where >+ CB: Fn(&Stream, i32, *mut c_void), > { > debug_assert_eq!(mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(s: *mut ffi::pa_stream, success: c_int, userdata: *mut c_void) >- where F: Fn(&Stream, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ s: *mut ffi::pa_stream, >+ success: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Stream, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let mut stm = stream::from_raw_ptr(s); > let result = uninitialized::<F>()(&mut stm, success, userdata); > forget(stm); > > result > } > >- let r = unsafe { ffi::pa_stream_update_timing_info(self.raw_mut(), Some(wrapped::<CB>), userdata) }; >+ let r = unsafe { >+ ffi::pa_stream_update_timing_info(self.raw_mut(), Some(wrapped::<CB>), userdata) >+ }; > if r.is_null() { > let err = if let Some(c) = self.get_context() { > c.errno() > } else { > ffi::PA_ERR_UNKNOWN > }; > return Err(ErrorCode::from_error_code(err)); > } >@@ -212,23 +241,25 @@ impl Stream { > > pub fn clear_state_callback(&self) { > unsafe { > ffi::pa_stream_set_state_callback(self.raw_mut(), None, ptr::null_mut()); > } > } > > pub fn set_state_callback<CB>(&self, _: CB, userdata: *mut c_void) >- where CB: Fn(&Stream, *mut c_void) >+ where >+ CB: Fn(&Stream, *mut c_void), > { > debug_assert_eq!(mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions > unsafe extern "C" fn wrapped<F>(s: *mut ffi::pa_stream, userdata: *mut c_void) >- where F: Fn(&Stream, *mut c_void) >+ where >+ F: Fn(&Stream, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let mut stm = stream::from_raw_ptr(s); > let result = uninitialized::<F>()(&mut stm, userdata); > forget(stm); > > result > } >@@ -240,23 +271,28 @@ impl Stream { > > pub fn clear_write_callback(&self) { > unsafe { > ffi::pa_stream_set_write_callback(self.raw_mut(), None, ptr::null_mut()); > } > } > > pub fn set_write_callback<CB>(&self, _: CB, userdata: *mut c_void) >- where CB: Fn(&Stream, usize, *mut c_void) >+ where >+ CB: Fn(&Stream, usize, *mut c_void), > { > debug_assert_eq!(mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(s: *mut ffi::pa_stream, nbytes: usize, userdata: *mut c_void) >- where F: Fn(&Stream, usize, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ s: *mut ffi::pa_stream, >+ nbytes: usize, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Stream, usize, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let mut stm = stream::from_raw_ptr(s); > let result = uninitialized::<F>()(&mut stm, nbytes, userdata); > forget(stm); > > result > } >@@ -268,45 +304,55 @@ impl Stream { > > pub fn clear_read_callback(&self) { > unsafe { > ffi::pa_stream_set_read_callback(self.raw_mut(), None, ptr::null_mut()); > } > } > > pub fn set_read_callback<CB>(&self, _: CB, userdata: *mut c_void) >- where CB: Fn(&Stream, usize, *mut c_void) >+ where >+ CB: Fn(&Stream, usize, *mut c_void), > { > debug_assert_eq!(mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(s: *mut ffi::pa_stream, nbytes: usize, userdata: *mut c_void) >- where F: Fn(&Stream, usize, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ s: *mut ffi::pa_stream, >+ nbytes: usize, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Stream, usize, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let mut stm = stream::from_raw_ptr(s); > let result = uninitialized::<F>()(&mut stm, nbytes, userdata); > forget(stm); > > result > } > > unsafe { > ffi::pa_stream_set_read_callback(self.raw_mut(), Some(wrapped::<CB>), userdata); > } > } > > pub fn cork<CB>(&self, b: i32, _: CB, userdata: *mut c_void) -> Result<Operation> >- where CB: Fn(&Stream, i32, *mut c_void) >+ where >+ CB: Fn(&Stream, i32, *mut c_void), > { > debug_assert_eq!(mem::size_of::<CB>(), 0); > > // See: A note about `wrapped` functions >- unsafe extern "C" fn wrapped<F>(s: *mut ffi::pa_stream, success: c_int, userdata: *mut c_void) >- where F: Fn(&Stream, i32, *mut c_void) >+ unsafe extern "C" fn wrapped<F>( >+ s: *mut ffi::pa_stream, >+ success: c_int, >+ userdata: *mut c_void, >+ ) where >+ F: Fn(&Stream, i32, *mut c_void), > { > use std::mem::{forget, uninitialized}; > let mut stm = stream::from_raw_ptr(s); > let result = uninitialized::<F>()(&mut stm, success, userdata); > forget(stm); > > result > } >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs >index 865aaac76b21..74d2410d637c 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/threaded_mainloop.rs >@@ -1,18 +1,18 @@ > // Copyright © 2017 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > >-use ErrorCode; >-use Result; > use ffi; > use mainloop_api; > use mainloop_api::MainloopApi; >+use ErrorCode; >+use Result; > > #[derive(Debug)] > pub struct ThreadedMainloop(*mut ffi::pa_threaded_mainloop); > > impl ThreadedMainloop { > pub unsafe fn from_raw_ptr(raw: *mut ffi::pa_threaded_mainloop) -> Self { > ThreadedMainloop(raw) > } >diff --git a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs >index 0723b1a186b9..8f18a49857da 100644 >--- a/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs >+++ b/media/libcubeb/cubeb-pulse-rs/pulse-rs/src/util.rs >@@ -7,17 +7,18 @@ use std::ffi::CStr; > use std::os::raw::c_char; > use std::ptr; > > pub trait UnwrapCStr { > fn unwrap_cstr(self) -> *const c_char; > } > > impl<'a, U> UnwrapCStr for U >- where U: Into<Option<&'a CStr>> >+where >+ U: Into<Option<&'a CStr>>, > { > fn unwrap_cstr(self) -> *const c_char { > self.into().map(|o| o.as_ptr()).unwrap_or(0 as *const _) > } > } > > pub fn map_to_mut_ptr<T, U, F: FnOnce(&T) -> *mut U>(t: Option<&mut T>, f: F) -> *mut U { > match t { >diff --git a/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs b/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs >index 088651f8cc86..effc32e700b3 100644 >--- a/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs >+++ b/media/libcubeb/cubeb-pulse-rs/src/backend/context.rs >@@ -1,16 +1,18 @@ > // Copyright © 2017-2018 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > > use backend::*; >-use cubeb_backend::{ffi, log_enabled, Context, ContextOps, DeviceCollectionRef, DeviceId, >- DeviceType, Error, Ops, Result, Stream, StreamParams, StreamParamsRef}; >+use cubeb_backend::{ >+ ffi, log_enabled, Context, ContextOps, DeviceCollectionRef, DeviceId, DeviceType, Error, Ops, >+ Result, Stream, StreamParams, StreamParamsRef, >+}; > use pulse::{self, ProplistExt}; > use pulse_ffi::*; > use semver; > use std::cell::RefCell; > use std::default::Default; > use std::ffi::{CStr, CString}; > use std::mem; > use std::os::raw::c_void; >diff --git a/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs b/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs >index 8e067e6caecb..9255be83af08 100644 >--- a/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs >+++ b/media/libcubeb/cubeb-pulse-rs/src/backend/mod.rs >@@ -1,17 +1,17 @@ > // Copyright © 2017-2018 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > > mod context; > mod cork_state; >-mod stream; > mod intern; >+mod stream; > > pub use self::context::PulseContext; > use self::intern::Intern; > pub use self::stream::Device; > pub use self::stream::PulseStream; > use std::ffi::CStr; > use std::os::raw::c_char; > >diff --git a/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs b/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs >index 96bee058f0b6..b314fa3dc7a3 100644 >--- a/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs >+++ b/media/libcubeb/cubeb-pulse-rs/src/backend/stream.rs >@@ -1,22 +1,24 @@ > // Copyright © 2017-2018 Mozilla Foundation > // > // This program is made available under an ISC-style license. See the > // accompanying file LICENSE for details. > >-use backend::*; > use backend::cork_state::CorkState; >-use cubeb_backend::{ffi, log_enabled, ChannelLayout, DeviceId, DeviceRef, Error, Result, >- SampleFormat, StreamOps, StreamParamsRef, StreamPrefs}; >+use backend::*; >+use cubeb_backend::{ >+ ffi, log_enabled, ChannelLayout, DeviceId, DeviceRef, Error, Result, SampleFormat, StreamOps, >+ StreamParamsRef, StreamPrefs, >+}; > use pulse::{self, CVolumeExt, ChannelMapExt, SampleSpecExt, StreamLatency, USecExt}; > use pulse_ffi::*; >-use std::{mem, ptr}; > use std::ffi::{CStr, CString}; > use std::os::raw::{c_long, c_void}; >+use std::{mem, ptr}; > > const PULSE_NO_GAIN: f32 = -1.0; > > /// Iterator interface to `ChannelLayout`. > /// > /// Iterates each channel in the set represented by `ChannelLayout`. > struct ChannelLayoutIter { > /// The layout set being iterated >@@ -375,17 +377,18 @@ impl<'ctx> Drop for PulseStream<'ctx> { > } > } > > impl<'ctx> StreamOps for PulseStream<'ctx> { > fn start(&mut self) -> Result<()> { > fn output_preroll(_: &pulse::MainloopApi, u: *mut c_void) { > let stm = unsafe { &mut *(u as *mut PulseStream) }; > if !stm.shutdown { >- let size = stm.output_stream >+ let size = stm >+ .output_stream > .as_ref() > .map_or(0, |s| s.writable_size().unwrap_or(0)); > stm.trigger_user_callback(ptr::null_mut(), size); > } > } > > self.shutdown = false; > self.cork(CorkState::uncork() | CorkState::notify()); >@@ -940,19 +943,19 @@ fn invalid_format() -> Error { > } > > fn not_supported() -> Error { > unsafe { Error::from_raw(ffi::CUBEB_ERROR_NOT_SUPPORTED) } > } > > #[cfg(all(test, not(feature = "pulse-dlopen")))] > mod test { >+ use super::layout_to_channel_map; > use cubeb_backend::ChannelLayout; > use pulse_ffi::*; >- use super::layout_to_channel_map; > > macro_rules! channel_tests { > {$($name: ident, $layout: ident => [ $($channels: ident),* ]),+} => { > $( > #[test] > fn $name() { > let layout = ChannelLayout::$layout; > let mut iter = super::channel_layout_iter(layout); >diff --git a/media/libcubeb/cubeb-pulse-rs/src/lib.rs b/media/libcubeb/cubeb-pulse-rs/src/lib.rs >index 7b73322aa29b..1aac80e3eae7 100644 >--- a/media/libcubeb/cubeb-pulse-rs/src/lib.rs >+++ b/media/libcubeb/cubeb-pulse-rs/src/lib.rs >@@ -6,12 +6,12 @@ > // accompanying file LICENSE for details. > > #[macro_use] > extern crate cubeb_backend; > extern crate pulse; > extern crate pulse_ffi; > extern crate semver; > >-mod capi; > mod backend; >+mod capi; > > pub use capi::pulse_rust_init; >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs >index ec92c952206a..a59792957b12 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/attribute_type.rs >@@ -1,50 +1,50 @@ >-use std::net::IpAddr; >-use std::str::FromStr; > use std::fmt; > use std::iter; >+use std::net::IpAddr; >+use std::str::FromStr; > >-use SdpType; > use error::SdpParserInternalError; >-use network::{parse_nettype, parse_addrtype, parse_unicast_addr}; >+use network::{parse_addrtype, parse_nettype, parse_unicast_addr}; >+use SdpType; > > #[derive(Debug, Clone, PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >-pub enum SdpSingleDirection{ >+#[cfg_attr(feature = "serialize", derive(Serialize))] >+pub enum SdpSingleDirection { > // This is explicitly 1 and 2 to match the defines in the C++ glue code. > Send = 1, > Recv = 2, > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributePayloadType { > PayloadType(u8), > Wildcard, // Wildcard means "*", > } > > #[derive(Debug, Clone, PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeCandidateTransport { > Udp, > Tcp, > } > > impl ToString for SdpAttributeCandidateTransport { > fn to_string(&self) -> String { > match *self { > SdpAttributeCandidateTransport::Udp => "UDP".to_string(), > SdpAttributeCandidateTransport::Tcp => "TCP".to_string(), > } > } > } > > #[derive(Debug, Clone, PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeCandidateType { > Host, > Srflx, > Prflx, > Relay, > } > > impl ToString for SdpAttributeCandidateType { >@@ -54,17 +54,17 @@ impl ToString for SdpAttributeCandidateType { > SdpAttributeCandidateType::Srflx => "srflx".to_string(), > SdpAttributeCandidateType::Prflx => "prflx".to_string(), > SdpAttributeCandidateType::Relay => "relay".to_string(), > } > } > } > > #[derive(Debug, Clone, PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeCandidateTcpType { > Active, > Passive, > Simultaneous, > } > > impl ToString for SdpAttributeCandidateTcpType { > fn to_string(&self) -> String { >@@ -72,17 +72,17 @@ impl ToString for SdpAttributeCandidateTcpType { > SdpAttributeCandidateTcpType::Active => "active".to_string(), > SdpAttributeCandidateTcpType::Passive => "passive".to_string(), > SdpAttributeCandidateTcpType::Simultaneous => "so".to_string(), > } > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeCandidate { > pub foundation: String, > pub component: u32, > pub transport: SdpAttributeCandidateTransport, > pub priority: u64, > pub address: IpAddr, > pub port: u32, > pub c_type: SdpAttributeCandidateType, >@@ -90,24 +90,25 @@ pub struct SdpAttributeCandidate { > pub rport: Option<u32>, > pub tcp_type: Option<SdpAttributeCandidateTcpType>, > pub generation: Option<u32>, > pub ufrag: Option<String>, > pub networkcost: Option<u32>, > } > > impl SdpAttributeCandidate { >- pub fn new(foundation: String, >- component: u32, >- transport: SdpAttributeCandidateTransport, >- priority: u64, >- address: IpAddr, >- port: u32, >- c_type: SdpAttributeCandidateType) >- -> SdpAttributeCandidate { >+ pub fn new( >+ foundation: String, >+ component: u32, >+ transport: SdpAttributeCandidateTransport, >+ priority: u64, >+ address: IpAddr, >+ port: u32, >+ c_type: SdpAttributeCandidateType, >+ ) -> SdpAttributeCandidate { > SdpAttributeCandidate { > foundation, > component, > transport, > priority, > address, > port, > c_type, >@@ -146,57 +147,59 @@ impl SdpAttributeCandidate { > } > > impl ToString for SdpAttributeCandidate { > fn to_string(&self) -> String { > macro_rules! option_to_string { > ($fmt_str:expr, $opt:expr) => { > match $opt { > Some(ref x) => format!($fmt_str, x.to_string()), >- None => "".to_string() >+ None => "".to_string(), > } > }; > } > >- format!("candidate:{foundation} {component_id} {transport} {priority} \ >- {connection_address} {port} typ {cand_type}\ >- {rel_addr}{rel_port}{tcp_type}{generation}{ufrag}{network_cost}", >- foundation = self.foundation, >- component_id = self.component.to_string(), >- transport = self.transport.to_string(), >- priority = self.priority.to_string(), >- connection_address = self.address.to_string(), >- port = self.port.to_string(), >- cand_type = self.c_type.to_string(), >- rel_addr = option_to_string!(" raddr {}", self.raddr), >- rel_port = option_to_string!(" rport {}", self.rport), >- tcp_type = option_to_string!(" tcptype {}", self.tcp_type), >- generation = option_to_string!(" generation {}", self.generation), >- ufrag = option_to_string!(" ufrag {}", self.ufrag), >- network_cost = option_to_string!(" network-cost {}", self.networkcost)) >+ format!( >+ "candidate:{foundation} {component_id} {transport} {priority} \ >+ {connection_address} {port} typ {cand_type}\ >+ {rel_addr}{rel_port}{tcp_type}{generation}{ufrag}{network_cost}", >+ foundation = self.foundation, >+ component_id = self.component.to_string(), >+ transport = self.transport.to_string(), >+ priority = self.priority.to_string(), >+ connection_address = self.address.to_string(), >+ port = self.port.to_string(), >+ cand_type = self.c_type.to_string(), >+ rel_addr = option_to_string!(" raddr {}", self.raddr), >+ rel_port = option_to_string!(" rport {}", self.rport), >+ tcp_type = option_to_string!(" tcptype {}", self.tcp_type), >+ generation = option_to_string!(" generation {}", self.generation), >+ ufrag = option_to_string!(" ufrag {}", self.ufrag), >+ network_cost = option_to_string!(" network-cost {}", self.networkcost) >+ ) > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeDtlsMessage { > Client(String), > Server(String), > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeRemoteCandidate { > pub component: u32, > pub address: IpAddr, > pub port: u32, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeSimulcastId { > pub id: String, > pub paused: bool, > } > > impl SdpAttributeSimulcastId { > pub fn new(idstr: &str) -> SdpAttributeSimulcastId { > if idstr.starts_with('~') { >@@ -210,41 +213,41 @@ impl SdpAttributeSimulcastId { > paused: false, > } > } > } > } > > #[repr(C)] > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeSimulcastVersion { > pub ids: Vec<SdpAttributeSimulcastId>, > } > > impl SdpAttributeSimulcastVersion { > pub fn new(idlist: &str) -> SdpAttributeSimulcastVersion { > SdpAttributeSimulcastVersion { > ids: idlist > .split(',') > .map(SdpAttributeSimulcastId::new) > .collect(), > } > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeSimulcast { > pub send: Vec<SdpAttributeSimulcastVersion>, > pub receive: Vec<SdpAttributeSimulcastVersion>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeRtcp { > pub port: u16, > pub unicast_addr: Option<IpAddr>, > } > > impl SdpAttributeRtcp { > pub fn new(port: u16) -> SdpAttributeRtcp { > SdpAttributeRtcp { >@@ -254,56 +257,56 @@ impl SdpAttributeRtcp { > } > > fn set_addr(&mut self, addr: IpAddr) { > self.unicast_addr = Some(addr) > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeRtcpFbType { > Ack = 0, > Ccm = 2, // This is explicitly 2 to make the conversion to the >- // enum used in the glue-code possible. The glue code has "app" >- // in the place of 1 >+ // enum used in the glue-code possible. The glue code has "app" >+ // in the place of 1 > Nack, > TrrInt, > Remb, >- TransCC >+ TransCC, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeRtcpFb { > pub payload_type: SdpAttributePayloadType, > pub feedback_type: SdpAttributeRtcpFbType, > pub parameter: String, > pub extra: String, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeDirection { > Recvonly, > Sendonly, > Sendrecv, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeExtmap { > pub id: u16, > pub direction: Option<SdpAttributeDirection>, > pub url: String, > pub extension_attributes: Option<String>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeFmtpParameters { > // H264 > // TODO(bug 1466859): Support sprop-parameter-sets > // pub static const max_sprop_len: u32 = 128, > // pub sprop_parameter_sets: [u8, max_sprop_len], > pub packetization_mode: u32, > pub level_asymmetry_allowed: bool, > pub profile_level_id: u32, >@@ -329,152 +332,151 @@ pub struct SdpAttributeFmtpParameters { > > // telephone-event > pub dtmf_tones: String, > > // Unknown > pub unknown_tokens: Vec<String>, > } > >- > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeFmtp { > pub payload_type: u8, > pub parameters: SdpAttributeFmtpParameters, > } > > #[derive(Clone, Copy)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeFingerprintHashType { > Sha1, > Sha224, > Sha256, > Sha384, > Sha512, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeFingerprint { > pub hash_algorithm: SdpAttributeFingerprintHashType, >- pub fingerprint: Vec<u8> >+ pub fingerprint: Vec<u8>, > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeImageAttrXYRange { >- Range(u32,u32,Option<u32>), // min, max, step >+ Range(u32, u32, Option<u32>), // min, max, step > DiscreteValues(Vec<u32>), > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeImageAttrSRange { >- Range(f32,f32), // min, max >+ Range(f32, f32), // min, max > DiscreteValues(Vec<f32>), > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeImageAttrPRange { > pub min: f32, > pub max: f32, > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeImageAttrSet { > pub x: SdpAttributeImageAttrXYRange, > pub y: SdpAttributeImageAttrXYRange, > pub sar: Option<SdpAttributeImageAttrSRange>, > pub par: Option<SdpAttributeImageAttrPRange>, > pub q: Option<f32>, > } > > #[derive(Debug, PartialEq, Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeImageAttrSetList { > Sets(Vec<SdpAttributeImageAttrSet>), > Wildcard, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeImageAttr { > pub pt: SdpAttributePayloadType, > pub send: SdpAttributeImageAttrSetList, > pub recv: SdpAttributeImageAttrSetList, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeSctpmap { > pub port: u16, > pub channels: u32, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeGroupSemantic { > LipSynchronization, > FlowIdentification, > SingleReservationFlow, > AlternateNetworkAddressType, > ForwardErrorCorrection, > DecodingDependency, > Bundle, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeGroup { > pub semantics: SdpAttributeGroupSemantic, > pub tags: Vec<String>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeMsid { > pub id: String, > pub appdata: Option<String>, > } > > #[derive(Clone, Debug)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeMsidSemantic { > pub semantic: String, > pub msids: Vec<String>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >-pub struct SdpAttributeRidParameters{ >+#[cfg_attr(feature = "serialize", derive(Serialize))] >+pub struct SdpAttributeRidParameters { > pub max_width: u32, > pub max_height: u32, > pub max_fps: u32, > pub max_fs: u32, > pub max_br: u32, > pub max_pps: u32, > >- pub unknown: Vec<String> >+ pub unknown: Vec<String>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeRid { > pub id: String, > pub direction: SdpSingleDirection, > pub formats: Vec<u16>, > pub params: SdpAttributeRidParameters, >- pub depends: Vec<String> >+ pub depends: Vec<String>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeRtpmap { > pub payload_type: u8, > pub codec_name: String, > pub frequency: u32, > pub channels: Option<u32>, > } > > impl SdpAttributeRtpmap { >@@ -488,26 +490,26 @@ impl SdpAttributeRtpmap { > } > > fn set_channels(&mut self, c: u32) { > self.channels = Some(c) > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttributeSetup { > Active, > Actpass, > Holdconn, > Passive, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpAttributeSsrc { > pub id: u32, > pub attribute: Option<String>, > pub value: Option<String>, > } > > impl SdpAttributeSsrc { > pub fn new(id: u32) -> SdpAttributeSsrc { >@@ -525,17 +527,17 @@ impl SdpAttributeSsrc { > let v: Vec<&str> = a.splitn(2, ':').collect(); > self.attribute = Some(v[0].to_string()); > self.value = Some(v[1].to_string()); > } > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpAttribute { > BundleOnly, > Candidate(SdpAttributeCandidate), > DtlsMessage(SdpAttributeDtlsMessage), > EndOfCandidates, > Extmap(SdpAttributeExtmap), > Fingerprint(SdpAttributeFingerprint), > Fmtp(SdpAttributeFmtp), >@@ -571,111 +573,111 @@ pub enum SdpAttribute { > Simulcast(SdpAttributeSimulcast), > Ssrc(SdpAttributeSsrc), > SsrcGroup(String), > } > > impl SdpAttribute { > pub fn allowed_at_session_level(&self) -> bool { > match *self { >- SdpAttribute::BundleOnly | >- SdpAttribute::Candidate(..) | >- SdpAttribute::Fmtp(..) | >- SdpAttribute::IceMismatch | >- SdpAttribute::ImageAttr(..) | >- SdpAttribute::Label(..) | >- SdpAttribute::MaxMessageSize(..) | >- SdpAttribute::MaxPtime(..) | >- SdpAttribute::Mid(..) | >- SdpAttribute::Msid(..) | >- SdpAttribute::Ptime(..) | >- SdpAttribute::Rid(..) | >- SdpAttribute::RemoteCandidate(..) | >- SdpAttribute::Rtpmap(..) | >- SdpAttribute::Rtcp(..) | >- SdpAttribute::Rtcpfb(..) | >- SdpAttribute::RtcpMux | >- SdpAttribute::RtcpRsize | >- SdpAttribute::Sctpmap(..) | >- SdpAttribute::SctpPort(..) | >- SdpAttribute::Simulcast(..) | >- SdpAttribute::Ssrc(..) | >- SdpAttribute::SsrcGroup(..) => false, >+ SdpAttribute::BundleOnly >+ | SdpAttribute::Candidate(..) >+ | SdpAttribute::Fmtp(..) >+ | SdpAttribute::IceMismatch >+ | SdpAttribute::ImageAttr(..) >+ | SdpAttribute::Label(..) >+ | SdpAttribute::MaxMessageSize(..) >+ | SdpAttribute::MaxPtime(..) >+ | SdpAttribute::Mid(..) >+ | SdpAttribute::Msid(..) >+ | SdpAttribute::Ptime(..) >+ | SdpAttribute::Rid(..) >+ | SdpAttribute::RemoteCandidate(..) >+ | SdpAttribute::Rtpmap(..) >+ | SdpAttribute::Rtcp(..) >+ | SdpAttribute::Rtcpfb(..) >+ | SdpAttribute::RtcpMux >+ | SdpAttribute::RtcpRsize >+ | SdpAttribute::Sctpmap(..) >+ | SdpAttribute::SctpPort(..) >+ | SdpAttribute::Simulcast(..) >+ | SdpAttribute::Ssrc(..) >+ | SdpAttribute::SsrcGroup(..) => false, > >- SdpAttribute::DtlsMessage{..} | >- SdpAttribute::EndOfCandidates | >- SdpAttribute::Extmap(..) | >- SdpAttribute::Fingerprint(..) | >- SdpAttribute::Group(..) | >- SdpAttribute::IceLite | >- SdpAttribute::IceOptions(..) | >- SdpAttribute::IcePwd(..) | >- SdpAttribute::IceUfrag(..) | >- SdpAttribute::Identity(..) | >- SdpAttribute::Inactive | >- SdpAttribute::MsidSemantic(..) | >- SdpAttribute::Recvonly | >- SdpAttribute::Sendonly | >- SdpAttribute::Sendrecv | >- SdpAttribute::Setup(..) => true, >+ SdpAttribute::DtlsMessage { .. } >+ | SdpAttribute::EndOfCandidates >+ | SdpAttribute::Extmap(..) >+ | SdpAttribute::Fingerprint(..) >+ | SdpAttribute::Group(..) >+ | SdpAttribute::IceLite >+ | SdpAttribute::IceOptions(..) >+ | SdpAttribute::IcePwd(..) >+ | SdpAttribute::IceUfrag(..) >+ | SdpAttribute::Identity(..) >+ | SdpAttribute::Inactive >+ | SdpAttribute::MsidSemantic(..) >+ | SdpAttribute::Recvonly >+ | SdpAttribute::Sendonly >+ | SdpAttribute::Sendrecv >+ | SdpAttribute::Setup(..) => true, > } > } > > pub fn allowed_at_media_level(&self) -> bool { > match *self { >- SdpAttribute::DtlsMessage{..} | >- SdpAttribute::Group(..) | >- SdpAttribute::IceLite | >- SdpAttribute::Identity(..) | >- SdpAttribute::MsidSemantic(..) => false, >+ SdpAttribute::DtlsMessage { .. } >+ | SdpAttribute::Group(..) >+ | SdpAttribute::IceLite >+ | SdpAttribute::Identity(..) >+ | SdpAttribute::MsidSemantic(..) => false, > >- SdpAttribute::BundleOnly | >- SdpAttribute::Candidate(..) | >- SdpAttribute::EndOfCandidates | >- SdpAttribute::Extmap(..) | >- SdpAttribute::Fingerprint(..) | >- SdpAttribute::Fmtp(..) | >- SdpAttribute::IceMismatch | >- SdpAttribute::IceOptions(..) | >- SdpAttribute::IcePwd(..) | >- SdpAttribute::IceUfrag(..) | >- SdpAttribute::ImageAttr(..) | >- SdpAttribute::Inactive | >- SdpAttribute::Label(..) | >- SdpAttribute::MaxMessageSize(..) | >- SdpAttribute::MaxPtime(..) | >- SdpAttribute::Mid(..) | >- SdpAttribute::Msid(..) | >- SdpAttribute::Ptime(..) | >- SdpAttribute::Rid(..) | >- SdpAttribute::Recvonly | >- SdpAttribute::RemoteCandidate(..) | >- SdpAttribute::Rtpmap(..) | >- SdpAttribute::Rtcp(..) | >- SdpAttribute::Rtcpfb(..) | >- SdpAttribute::RtcpMux | >- SdpAttribute::RtcpRsize | >- SdpAttribute::Sctpmap(..) | >- SdpAttribute::SctpPort(..) | >- SdpAttribute::Sendonly | >- SdpAttribute::Sendrecv | >- SdpAttribute::Setup(..) | >- SdpAttribute::Simulcast(..) | >- SdpAttribute::Ssrc(..) | >- SdpAttribute::SsrcGroup(..) => true, >+ SdpAttribute::BundleOnly >+ | SdpAttribute::Candidate(..) >+ | SdpAttribute::EndOfCandidates >+ | SdpAttribute::Extmap(..) >+ | SdpAttribute::Fingerprint(..) >+ | SdpAttribute::Fmtp(..) >+ | SdpAttribute::IceMismatch >+ | SdpAttribute::IceOptions(..) >+ | SdpAttribute::IcePwd(..) >+ | SdpAttribute::IceUfrag(..) >+ | SdpAttribute::ImageAttr(..) >+ | SdpAttribute::Inactive >+ | SdpAttribute::Label(..) >+ | SdpAttribute::MaxMessageSize(..) >+ | SdpAttribute::MaxPtime(..) >+ | SdpAttribute::Mid(..) >+ | SdpAttribute::Msid(..) >+ | SdpAttribute::Ptime(..) >+ | SdpAttribute::Rid(..) >+ | SdpAttribute::Recvonly >+ | SdpAttribute::RemoteCandidate(..) >+ | SdpAttribute::Rtpmap(..) >+ | SdpAttribute::Rtcp(..) >+ | SdpAttribute::Rtcpfb(..) >+ | SdpAttribute::RtcpMux >+ | SdpAttribute::RtcpRsize >+ | SdpAttribute::Sctpmap(..) >+ | SdpAttribute::SctpPort(..) >+ | SdpAttribute::Sendonly >+ | SdpAttribute::Sendrecv >+ | SdpAttribute::Setup(..) >+ | SdpAttribute::Simulcast(..) >+ | SdpAttribute::Ssrc(..) >+ | SdpAttribute::SsrcGroup(..) => true, > } > } > } > > impl fmt::Display for SdpAttribute { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > let printable = match *self { > SdpAttribute::BundleOnly => "bundle-only", > SdpAttribute::Candidate(..) => "candidate", >- SdpAttribute::DtlsMessage{..} => "dtls-message", >+ SdpAttribute::DtlsMessage { .. } => "dtls-message", > SdpAttribute::EndOfCandidates => "end-of-candidates", > SdpAttribute::Extmap(..) => "extmap", > SdpAttribute::Fingerprint(..) => "fingerprint", > SdpAttribute::Fmtp(..) => "fmtp", > SdpAttribute::Group(..) => "group", > SdpAttribute::IceLite => "ice-lite", > SdpAttribute::IceMismatch => "ice-mismatch", > SdpAttribute::IceOptions(..) => "ice-options", >@@ -718,28 +720,22 @@ impl FromStr for SdpAttribute { > let tokens: Vec<_> = line.splitn(2, ':').collect(); > let name = tokens[0].to_lowercase(); > let val = match tokens.get(1) { > Some(x) => x.trim(), > None => "", > }; > if tokens.len() > 1 { > match name.as_str() { >- "bundle-only" | >- "end-of-candidates" | >- "ice-lite" | >- "ice-mismatch" | >- "inactive" | >- "recvonly" | >- "rtcp-mux" | >- "rtcp-rsize" | >- "sendonly" | >- "sendrecv" => { >- return Err(SdpParserInternalError::Generic(format!("{} attribute is not allowed to have a value", >- name))); >+ "bundle-only" | "end-of-candidates" | "ice-lite" | "ice-mismatch" | "inactive" >+ | "recvonly" | "rtcp-mux" | "rtcp-rsize" | "sendonly" | "sendrecv" => { >+ return Err(SdpParserInternalError::Generic(format!( >+ "{} attribute is not allowed to have a value", >+ name >+ ))); > } > _ => (), > } > } > match name.as_str() { > "bundle-only" => Ok(SdpAttribute::BundleOnly), > "dtls-message" => parse_dtls_message(val), > "end-of-candidates" => Ok(SdpAttribute::EndOfCandidates), >@@ -751,17 +747,17 @@ impl FromStr for SdpAttribute { > "imageattr" => parse_image_attr(val), > "inactive" => Ok(SdpAttribute::Inactive), > "label" => Ok(SdpAttribute::Label(string_or_empty(val)?)), > "max-message-size" => Ok(SdpAttribute::MaxMessageSize(val.parse()?)), > "maxptime" => Ok(SdpAttribute::MaxPtime(val.parse()?)), > "mid" => Ok(SdpAttribute::Mid(string_or_empty(val)?)), > "msid-semantic" => parse_msid_semantic(val), > "ptime" => Ok(SdpAttribute::Ptime(val.parse()?)), >- "rid" => parse_rid(val), >+ "rid" => parse_rid(val), > "recvonly" => Ok(SdpAttribute::Recvonly), > "rtcp-mux" => Ok(SdpAttribute::RtcpMux), > "rtcp-rsize" => Ok(SdpAttribute::RtcpRsize), > "sendonly" => Ok(SdpAttribute::Sendonly), > "sendrecv" => Ok(SdpAttribute::Sendrecv), > "ssrc-group" => Ok(SdpAttribute::SsrcGroup(string_or_empty(val)?)), > "sctp-port" => parse_sctp_port(val), > "candidate" => parse_candidate(val), >@@ -774,19 +770,20 @@ impl FromStr for SdpAttribute { > "remote-candidates" => parse_remote_candidates(val), > "rtpmap" => parse_rtpmap(val), > "rtcp" => parse_rtcp(val), > "rtcp-fb" => parse_rtcp_fb(val), > "sctpmap" => parse_sctpmap(val), > "setup" => parse_setup(val), > "simulcast" => parse_simulcast(val), > "ssrc" => parse_ssrc(val), >- _ => { >- Err(SdpParserInternalError::Unsupported(format!("Unknown attribute type {}", name))) >- } >+ _ => Err(SdpParserInternalError::Unsupported(format!( >+ "Unknown attribute type {}", >+ name >+ ))), > } > } > } > > #[derive(Clone, PartialEq)] > pub enum SdpAttributeType { > BundleOnly, > Candidate, >@@ -827,138 +824,150 @@ pub enum SdpAttributeType { > Simulcast, > Ssrc, > SsrcGroup, > } > > impl<'a> From<&'a SdpAttribute> for SdpAttributeType { > fn from(other: &SdpAttribute) -> Self { > match *other { >- SdpAttribute::BundleOnly{..} => SdpAttributeType::BundleOnly, >- SdpAttribute::Candidate{..} => SdpAttributeType::Candidate, >- SdpAttribute::DtlsMessage{..} => SdpAttributeType::DtlsMessage, >- SdpAttribute::EndOfCandidates{..} => SdpAttributeType::EndOfCandidates, >- SdpAttribute::Extmap{..} => SdpAttributeType::Extmap, >- SdpAttribute::Fingerprint{..} => SdpAttributeType::Fingerprint, >- SdpAttribute::Fmtp{..} => SdpAttributeType::Fmtp, >- SdpAttribute::Group{..} => SdpAttributeType::Group, >- SdpAttribute::IceLite{..} => SdpAttributeType::IceLite, >- SdpAttribute::IceMismatch{..} => SdpAttributeType::IceMismatch, >- SdpAttribute::IceOptions{..} => SdpAttributeType::IceOptions, >- SdpAttribute::IcePwd{..} => SdpAttributeType::IcePwd, >- SdpAttribute::IceUfrag{..} => SdpAttributeType::IceUfrag, >- SdpAttribute::Identity{..} => SdpAttributeType::Identity, >- SdpAttribute::ImageAttr{..} => SdpAttributeType::ImageAttr, >- SdpAttribute::Inactive{..} => SdpAttributeType::Inactive, >- SdpAttribute::Label{..} => SdpAttributeType::Label, >- SdpAttribute::MaxMessageSize{..} => SdpAttributeType::MaxMessageSize, >- SdpAttribute::MaxPtime{..} => SdpAttributeType::MaxPtime, >- SdpAttribute::Mid{..} => SdpAttributeType::Mid, >- SdpAttribute::Msid{..} => SdpAttributeType::Msid, >- SdpAttribute::MsidSemantic{..} => SdpAttributeType::MsidSemantic, >- SdpAttribute::Ptime{..} => SdpAttributeType::Ptime, >- SdpAttribute::Rid{..} => SdpAttributeType::Rid, >- SdpAttribute::Recvonly{..} => SdpAttributeType::Recvonly, >- SdpAttribute::RemoteCandidate{..} => SdpAttributeType::RemoteCandidate, >- SdpAttribute::Rtcp{..} => SdpAttributeType::Rtcp, >- SdpAttribute::Rtcpfb{..} => SdpAttributeType::Rtcpfb, >- SdpAttribute::RtcpMux{..} => SdpAttributeType::RtcpMux, >- SdpAttribute::RtcpRsize{..} => SdpAttributeType::RtcpRsize, >- SdpAttribute::Rtpmap{..} => SdpAttributeType::Rtpmap, >- SdpAttribute::Sctpmap{..} => SdpAttributeType::Sctpmap, >- SdpAttribute::SctpPort{..} => SdpAttributeType::SctpPort, >- SdpAttribute::Sendonly{..} => SdpAttributeType::Sendonly, >- SdpAttribute::Sendrecv{..} => SdpAttributeType::Sendrecv, >- SdpAttribute::Setup{..} => SdpAttributeType::Setup, >- SdpAttribute::Simulcast{..} => SdpAttributeType::Simulcast, >- SdpAttribute::Ssrc{..} => SdpAttributeType::Ssrc, >- SdpAttribute::SsrcGroup{..} => SdpAttributeType::SsrcGroup >+ SdpAttribute::BundleOnly { .. } => SdpAttributeType::BundleOnly, >+ SdpAttribute::Candidate { .. } => SdpAttributeType::Candidate, >+ SdpAttribute::DtlsMessage { .. } => SdpAttributeType::DtlsMessage, >+ SdpAttribute::EndOfCandidates { .. } => SdpAttributeType::EndOfCandidates, >+ SdpAttribute::Extmap { .. } => SdpAttributeType::Extmap, >+ SdpAttribute::Fingerprint { .. } => SdpAttributeType::Fingerprint, >+ SdpAttribute::Fmtp { .. } => SdpAttributeType::Fmtp, >+ SdpAttribute::Group { .. } => SdpAttributeType::Group, >+ SdpAttribute::IceLite { .. } => SdpAttributeType::IceLite, >+ SdpAttribute::IceMismatch { .. } => SdpAttributeType::IceMismatch, >+ SdpAttribute::IceOptions { .. } => SdpAttributeType::IceOptions, >+ SdpAttribute::IcePwd { .. } => SdpAttributeType::IcePwd, >+ SdpAttribute::IceUfrag { .. } => SdpAttributeType::IceUfrag, >+ SdpAttribute::Identity { .. } => SdpAttributeType::Identity, >+ SdpAttribute::ImageAttr { .. } => SdpAttributeType::ImageAttr, >+ SdpAttribute::Inactive { .. } => SdpAttributeType::Inactive, >+ SdpAttribute::Label { .. } => SdpAttributeType::Label, >+ SdpAttribute::MaxMessageSize { .. } => SdpAttributeType::MaxMessageSize, >+ SdpAttribute::MaxPtime { .. } => SdpAttributeType::MaxPtime, >+ SdpAttribute::Mid { .. } => SdpAttributeType::Mid, >+ SdpAttribute::Msid { .. } => SdpAttributeType::Msid, >+ SdpAttribute::MsidSemantic { .. } => SdpAttributeType::MsidSemantic, >+ SdpAttribute::Ptime { .. } => SdpAttributeType::Ptime, >+ SdpAttribute::Rid { .. } => SdpAttributeType::Rid, >+ SdpAttribute::Recvonly { .. } => SdpAttributeType::Recvonly, >+ SdpAttribute::RemoteCandidate { .. } => SdpAttributeType::RemoteCandidate, >+ SdpAttribute::Rtcp { .. } => SdpAttributeType::Rtcp, >+ SdpAttribute::Rtcpfb { .. } => SdpAttributeType::Rtcpfb, >+ SdpAttribute::RtcpMux { .. } => SdpAttributeType::RtcpMux, >+ SdpAttribute::RtcpRsize { .. } => SdpAttributeType::RtcpRsize, >+ SdpAttribute::Rtpmap { .. } => SdpAttributeType::Rtpmap, >+ SdpAttribute::Sctpmap { .. } => SdpAttributeType::Sctpmap, >+ SdpAttribute::SctpPort { .. } => SdpAttributeType::SctpPort, >+ SdpAttribute::Sendonly { .. } => SdpAttributeType::Sendonly, >+ SdpAttribute::Sendrecv { .. } => SdpAttributeType::Sendrecv, >+ SdpAttribute::Setup { .. } => SdpAttributeType::Setup, >+ SdpAttribute::Simulcast { .. } => SdpAttributeType::Simulcast, >+ SdpAttribute::Ssrc { .. } => SdpAttributeType::Ssrc, >+ SdpAttribute::SsrcGroup { .. } => SdpAttributeType::SsrcGroup, > } > } > } > >- > fn string_or_empty(to_parse: &str) -> Result<String, SdpParserInternalError> { > if to_parse.is_empty() { >- Err(SdpParserInternalError::Generic("This attribute is required to have a value" >- .to_string())) >+ Err(SdpParserInternalError::Generic( >+ "This attribute is required to have a value".to_string(), >+ )) > } else { > Ok(to_parse.to_string()) > } > } > >-fn parse_payload_type(to_parse: &str) -> Result<SdpAttributePayloadType, SdpParserInternalError> >-{ >+fn parse_payload_type(to_parse: &str) -> Result<SdpAttributePayloadType, SdpParserInternalError> { > Ok(match to_parse { >- "*" => SdpAttributePayloadType::Wildcard, >- _ => SdpAttributePayloadType::PayloadType(to_parse.parse::<u8>()?) >- }) >+ "*" => SdpAttributePayloadType::Wildcard, >+ _ => SdpAttributePayloadType::PayloadType(to_parse.parse::<u8>()?), >+ }) > } > > fn parse_single_direction(to_parse: &str) -> Result<SdpSingleDirection, SdpParserInternalError> { > match to_parse { > "send" => Ok(SdpSingleDirection::Send), > "recv" => Ok(SdpSingleDirection::Recv), > x @ _ => Err(SdpParserInternalError::Generic( >- format!("Unknown direction description found: '{:}'",x).to_string() >- )) >+ format!("Unknown direction description found: '{:}'", x).to_string(), >+ )), > } > } > > fn parse_sctp_port(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let port = to_parse.parse()?; > if port > 65535 { >- return Err(SdpParserInternalError::Generic(format!("Sctpport port {} can only be a bit 16bit number", >- port))); >+ return Err(SdpParserInternalError::Generic(format!( >+ "Sctpport port {} can only be a bit 16bit number", >+ port >+ ))); > } > Ok(SdpAttribute::SctpPort(port)) > } > > fn parse_candidate(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<&str> = to_parse.split_whitespace().collect(); > if tokens.len() < 8 { >- return Err(SdpParserInternalError::Generic("Candidate needs to have minimum eigth tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Candidate needs to have minimum eigth tokens".to_string(), >+ )); > } > let component = tokens[1].parse::<u32>()?; > let transport = match tokens[2].to_lowercase().as_ref() { > "udp" => SdpAttributeCandidateTransport::Udp, > "tcp" => SdpAttributeCandidateTransport::Tcp, > _ => { >- return Err(SdpParserInternalError::Generic("Unknonw candidate transport value" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Unknonw candidate transport value".to_string(), >+ )) > } > }; > let priority = tokens[3].parse::<u64>()?; > let address = parse_unicast_addr(tokens[4])?; > let port = tokens[5].parse::<u32>()?; > if port > 65535 { >- return Err(SdpParserInternalError::Generic("ICE candidate port can only be a bit 16bit number".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "ICE candidate port can only be a bit 16bit number".to_string(), >+ )); > } > match tokens[6].to_lowercase().as_ref() { > "typ" => (), > _ => { >- return Err(SdpParserInternalError::Generic("Candidate attribute token must be 'typ'" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Candidate attribute token must be 'typ'".to_string(), >+ )) > } > }; > let cand_type = match tokens[7].to_lowercase().as_ref() { > "host" => SdpAttributeCandidateType::Host, > "srflx" => SdpAttributeCandidateType::Srflx, > "prflx" => SdpAttributeCandidateType::Prflx, > "relay" => SdpAttributeCandidateType::Relay, >- _ => return Err(SdpParserInternalError::Generic("Unknow candidate type value".to_string())), >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "Unknow candidate type value".to_string(), >+ )) >+ } > }; >- let mut cand = SdpAttributeCandidate::new(tokens[0].to_string(), >- component, >- transport, >- priority, >- address, >- port, >- cand_type); >+ let mut cand = SdpAttributeCandidate::new( >+ tokens[0].to_string(), >+ component, >+ transport, >+ priority, >+ address, >+ port, >+ cand_type, >+ ); > if tokens.len() > 8 { > let mut index = 8; > while tokens.len() > index + 1 { > match tokens[index].to_lowercase().as_ref() { > "generation" => { > let generation = tokens[index + 1].parse::<u32>()?; > cand.set_generation(generation); > index += 2; >@@ -971,183 +980,193 @@ fn parse_candidate(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalErro > "raddr" => { > let addr = parse_unicast_addr(tokens[index + 1])?; > cand.set_remote_address(addr); > index += 2; > } > "rport" => { > let port = tokens[index + 1].parse::<u32>()?; > if port > 65535 { >- return Err(SdpParserInternalError::Generic( "ICE candidate rport can only be a bit 16bit number".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "ICE candidate rport can only be a bit 16bit number".to_string(), >+ )); > } > cand.set_remote_port(port); > index += 2; > } > "tcptype" => { > cand.set_tcp_type(match tokens[index + 1].to_lowercase().as_ref() { >- "active" => SdpAttributeCandidateTcpType::Active, >- "passive" => SdpAttributeCandidateTcpType::Passive, >- "so" => SdpAttributeCandidateTcpType::Simultaneous, >- _ => { >- return Err(SdpParserInternalError::Generic("Unknown tcptype value in candidate line".to_string())) >+ "active" => SdpAttributeCandidateTcpType::Active, >+ "passive" => SdpAttributeCandidateTcpType::Passive, >+ "so" => SdpAttributeCandidateTcpType::Simultaneous, >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "Unknown tcptype value in candidate line".to_string(), >+ )) > } >- }); >+ }); > index += 2; > } > "ufrag" => { > let ufrag = tokens[index + 1]; > cand.set_ufrag(ufrag.to_string()); > index += 2; > } > _ => { >- return Err(SdpParserInternalError::Unsupported("Uknown candidate extension name" >- .to_string())) >+ return Err(SdpParserInternalError::Unsupported( >+ "Uknown candidate extension name".to_string(), >+ )) > } > }; > } > } > Ok(SdpAttribute::Candidate(cand)) > } > > fn parse_dtls_message(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { >- let tokens:Vec<&str> = to_parse.split(" ").collect(); >+ let tokens: Vec<&str> = to_parse.split(" ").collect(); > > if tokens.len() != 2 { > return Err(SdpParserInternalError::Generic( >- "dtls-message must have a role token and a value token.".to_string() >+ "dtls-message must have a role token and a value token.".to_string(), > )); > } > > Ok(SdpAttribute::DtlsMessage(match tokens[0] { > "client" => SdpAttributeDtlsMessage::Client(tokens[1].to_string()), > "server" => SdpAttributeDtlsMessage::Server(tokens[1].to_string()), > e @ _ => { > return Err(SdpParserInternalError::Generic( >- format!("dtls-message has unknown role token '{}'",e).to_string() >+ format!("dtls-message has unknown role token '{}'", e).to_string(), > )); > } > })) > } > > // ABNF for extmap is defined in RFC 5285 > // https://tools.ietf.org/html/rfc5285#section-7 > fn parse_extmap(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<&str> = to_parse.split_whitespace().collect(); > if tokens.len() < 2 { >- return Err(SdpParserInternalError::Generic("Extmap needs to have at least two tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Extmap needs to have at least two tokens".to_string(), >+ )); > } > let id: u16; > let mut direction: Option<SdpAttributeDirection> = None; > if tokens[0].find('/') == None { > id = tokens[0].parse::<u16>()?; > } else { > let id_dir: Vec<&str> = tokens[0].splitn(2, '/').collect(); > id = id_dir[0].parse::<u16>()?; > direction = Some(match id_dir[1].to_lowercase().as_ref() { >- "recvonly" => SdpAttributeDirection::Recvonly, >- "sendonly" => SdpAttributeDirection::Sendonly, >- "sendrecv" => SdpAttributeDirection::Sendrecv, >- _ => { >- return Err(SdpParserInternalError::Generic("Unsupported direction in extmap value".to_string())) >- } >- }) >+ "recvonly" => SdpAttributeDirection::Recvonly, >+ "sendonly" => SdpAttributeDirection::Sendonly, >+ "sendrecv" => SdpAttributeDirection::Sendrecv, >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "Unsupported direction in extmap value".to_string(), >+ )) >+ } >+ }) > } > // Consider replacing to_parse.split_whitespace() above with splitn on space. Would we want the pattern to split on any amout of any kind of whitespace? > let extension_attributes = if tokens.len() == 2 { > None > } else { > let ext_string: String = tokens[2..].join(" "); > if !valid_byte_string(&ext_string) { >- return Err(SdpParserInternalError::Generic("Illegal character in extmap extension attributes".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Illegal character in extmap extension attributes".to_string(), >+ )); > } > Some(ext_string) > }; > Ok(SdpAttribute::Extmap(SdpAttributeExtmap { >- id, >- direction, >- url: tokens[1].to_string(), >- extension_attributes: extension_attributes, >- })) >+ id, >+ direction, >+ url: tokens[1].to_string(), >+ extension_attributes: extension_attributes, >+ })) > } > > fn parse_fingerprint(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<&str> = to_parse.split_whitespace().collect(); > if tokens.len() != 2 { >- return Err(SdpParserInternalError::Generic("Fingerprint needs to have two tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Fingerprint needs to have two tokens".to_string(), >+ )); > } > > let fingerprint_token = tokens[1].to_string(); >- let parse_tokens = |expected_len| -> Result<Vec<u8>, SdpParserInternalError>{ >- let bytes = fingerprint_token.split(":") >- .map(|byte_token| { >- if byte_token.len() != 2 { >- return Err(SdpParserInternalError::Generic( >- "fingerpint's byte tokens must have 2 hexdigits" >- .to_string() >- )) >- } >- Ok(u8::from_str_radix(byte_token, 16)?) >- }) >- .collect::<Result<Vec<u8>,_>>()?; >+ let parse_tokens = |expected_len| -> Result<Vec<u8>, SdpParserInternalError> { >+ let bytes = fingerprint_token >+ .split(":") >+ .map(|byte_token| { >+ if byte_token.len() != 2 { >+ return Err(SdpParserInternalError::Generic( >+ "fingerpint's byte tokens must have 2 hexdigits".to_string(), >+ )); >+ } >+ Ok(u8::from_str_radix(byte_token, 16)?) >+ }).collect::<Result<Vec<u8>, _>>()?; > > if bytes.len() != expected_len { >- return Err(SdpParserInternalError::Generic( >- format!("fingerprint has {} bytes but should have {} bytes", >- bytes.len(), expected_len) >- )) >+ return Err(SdpParserInternalError::Generic(format!( >+ "fingerprint has {} bytes but should have {} bytes", >+ bytes.len(), >+ expected_len >+ ))); > } > > Ok(bytes) > }; > >- > let hash_algorithm = match tokens[0] { > "sha-1" => SdpAttributeFingerprintHashType::Sha1, > "sha-224" => SdpAttributeFingerprintHashType::Sha224, > "sha-256" => SdpAttributeFingerprintHashType::Sha256, > "sha-384" => SdpAttributeFingerprintHashType::Sha384, > "sha-512" => SdpAttributeFingerprintHashType::Sha512, > unknown => { >- return Err(SdpParserInternalError::Unsupported( >- format!("fingerprint contains an unsupported hash algorithm '{}'", unknown) >- )) >+ return Err(SdpParserInternalError::Unsupported(format!( >+ "fingerprint contains an unsupported hash algorithm '{}'", >+ unknown >+ ))) > } > }; > > let fingerprint = match hash_algorithm { > SdpAttributeFingerprintHashType::Sha1 => parse_tokens(20)?, > SdpAttributeFingerprintHashType::Sha224 => parse_tokens(28)?, > SdpAttributeFingerprintHashType::Sha256 => parse_tokens(32)?, > SdpAttributeFingerprintHashType::Sha384 => parse_tokens(48)?, > SdpAttributeFingerprintHashType::Sha512 => parse_tokens(64)?, > }; > > Ok(SdpAttribute::Fingerprint(SdpAttributeFingerprint { >- hash_algorithm, >- fingerprint, >- })) >+ hash_algorithm, >+ fingerprint, >+ })) > } > > fn parse_fmtp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { >- let tokens: Vec<&str> = to_parse.splitn(2," ").collect(); >+ let tokens: Vec<&str> = to_parse.splitn(2, " ").collect(); > > if tokens.len() != 2 { > return Err(SdpParserInternalError::Unsupported( >- "Fmtp attributes require a payload type and a parameter block.".to_string() >+ "Fmtp attributes require a payload type and a parameter block.".to_string(), > )); > } > > let payload_token = tokens[0]; > let parameter_token = tokens[1]; > >- > // Default initiliaze SdpAttributeFmtpParameters >- let mut parameters = SdpAttributeFmtpParameters{ >+ let mut parameters = SdpAttributeFmtpParameters { > packetization_mode: 0, > level_asymmetry_allowed: false, > profile_level_id: 0x420010, > max_fs: 0, > max_cpb: 0, > max_dpb: 0, > max_br: 0, > max_mbps: 0, >@@ -1161,198 +1180,214 @@ fn parse_fmtp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > dtmf_tones: "".to_string(), > unknown_tokens: Vec::new(), > }; > > if parameter_token.contains("=") { > let parameter_tokens: Vec<&str> = parameter_token.split(";").collect(); > > for parameter_token in parameter_tokens.iter() { >- let name_value_pair: Vec<&str> = parameter_token.splitn(2,"=").collect(); >+ let name_value_pair: Vec<&str> = parameter_token.splitn(2, "=").collect(); > > if name_value_pair.len() != 2 { > return Err(SdpParserInternalError::Generic( > "A fmtp parameter must be either a telephone event, a parameter list or >- a red codec list".to_string() >- )) >+ a red codec list" >+ .to_string(), >+ )); > } > >- let parse_bool = |val: &str, param_name: &str| -> Result<bool,SdpParserInternalError> { >- match val.parse::<u8>()? { >- 0 => Ok(false), >- 1 => Ok(true), >- _ => return Err(SdpParserInternalError::Generic( >- format!("The fmtp parameter '{:}' must be 0 or 1", param_name) >- .to_string() >- )) >- } >- }; >+ let parse_bool = >+ |val: &str, param_name: &str| -> Result<bool, SdpParserInternalError> { >+ match val.parse::<u8>()? { >+ 0 => Ok(false), >+ 1 => Ok(true), >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ format!("The fmtp parameter '{:}' must be 0 or 1", param_name) >+ .to_string(), >+ )) >+ } >+ } >+ }; > > let parameter_name = name_value_pair[0]; > let parameter_val = name_value_pair[1]; > > match parameter_name.to_uppercase().as_str() { > // H264 >- "PROFILE-LEVEL-ID" => parameters.profile_level_id = >- match u32::from_str_radix(parameter_val,16)? { >- x @ 0 ... 0xffffff => x, >- _ => return Err(SdpParserInternalError::Generic( >- "The fmtp parameter 'profile-level-id' must be in range [0,0xffffff]" >- .to_string() >- )) >- }, >- "PACKETIZATION-MODE" => parameters.packetization_mode = >- match parameter_val.parse::<u32>()? { >- x @ 0...2 => x, >- _ => return Err(SdpParserInternalError::Generic( >- "The fmtp parameter 'packetization-mode' must be 0,1 or 2" >- .to_string() >- )) >- }, >- "LEVEL-ASYMMETRY-ALLOWED" => parameters.level_asymmetry_allowed = >- parse_bool(parameter_val,"level-asymmetry-allowed")?, >+ "PROFILE-LEVEL-ID" => { >+ parameters.profile_level_id = match u32::from_str_radix(parameter_val, 16)? { >+ x @ 0...0xffffff => x, >+ _ => return Err(SdpParserInternalError::Generic( >+ "The fmtp parameter 'profile-level-id' must be in range [0,0xffffff]" >+ .to_string(), >+ )), >+ } >+ } >+ "PACKETIZATION-MODE" => { >+ parameters.packetization_mode = match parameter_val.parse::<u32>()? { >+ x @ 0...2 => x, >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "The fmtp parameter 'packetization-mode' must be 0,1 or 2" >+ .to_string(), >+ )) >+ } >+ } >+ } >+ "LEVEL-ASYMMETRY-ALLOWED" => { >+ parameters.level_asymmetry_allowed = >+ parse_bool(parameter_val, "level-asymmetry-allowed")? >+ } > "MAX-MBPS" => parameters.max_mbps = parameter_val.parse::<u32>()?, > "MAX-FS" => parameters.max_fs = parameter_val.parse::<u32>()?, > "MAX-CPB" => parameters.max_cpb = parameter_val.parse::<u32>()?, > "MAX-DPB" => parameters.max_dpb = parameter_val.parse::<u32>()?, > "MAX-BR" => parameters.max_br = parameter_val.parse::<u32>()?, > > // VP8 and VP9 > "MAX-FR" => parameters.max_fr = parameter_val.parse::<u32>()?, > > //Opus > "MAXPLAYBACKRATE" => parameters.maxplaybackrate = parameter_val.parse::<u32>()?, >- "USEDTX" => parameters.usedtx = parse_bool(parameter_val,"usedtx")?, >- "STEREO" => parameters.stereo = parse_bool(parameter_val,"stereo")?, >- "USEINBANDFEC" => parameters.useinbandfec = >- parse_bool(parameter_val,"useinbandfec")?, >- "CBR" => parameters.cbr = parse_bool(parameter_val,"cbr")?, >- _ => { >- parameters.unknown_tokens.push(parameter_token.to_string()) >+ "USEDTX" => parameters.usedtx = parse_bool(parameter_val, "usedtx")?, >+ "STEREO" => parameters.stereo = parse_bool(parameter_val, "stereo")?, >+ "USEINBANDFEC" => { >+ parameters.useinbandfec = parse_bool(parameter_val, "useinbandfec")? > } >+ "CBR" => parameters.cbr = parse_bool(parameter_val, "cbr")?, >+ _ => parameters.unknown_tokens.push(parameter_token.to_string()), > } > } > } else { > if parameter_token.contains("/") { > let encodings: Vec<&str> = parameter_token.split("/").collect(); > > for encoding in encodings { > match encoding.parse::<u8>()? { > x @ 0...128 => parameters.encodings.push(x), >- _ => return Err(SdpParserInternalError::Generic( >- "Red codec must be in range [0,128]".to_string() >- )) >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "Red codec must be in range [0,128]".to_string(), >+ )) >+ } > } > } >- } else { // This is the case for the 'telephone-event' codec >+ } else { >+ // This is the case for the 'telephone-event' codec > let dtmf_tones: Vec<&str> = parameter_token.split(",").collect(); > let mut dtmf_tone_is_ok = true; > > // This closure verifies the output of some_number_as_string.parse::<u8>().ok() like calls >- let validate_digits = |digit_option: Option<u8> | -> Option<u8> { >- match digit_option{ >+ let validate_digits = |digit_option: Option<u8>| -> Option<u8> { >+ match digit_option { > Some(x) => match x { > 0...100 => Some(x), > _ => None, > }, > None => None, > } > }; > > // This loop does some sanity checking on the passed dtmf tones > for dtmf_tone in dtmf_tones { >- let dtmf_tone_range: Vec<&str> = dtmf_tone.splitn(2,"-").collect(); >+ let dtmf_tone_range: Vec<&str> = dtmf_tone.splitn(2, "-").collect(); > > dtmf_tone_is_ok = match dtmf_tone_range.len() { > // In this case the dtmf tone is a range > 2 => { > match validate_digits(dtmf_tone_range[0].parse::<u8>().ok()) { >- Some(l) => match validate_digits(dtmf_tone_range[1].parse::<u8>().ok()) { >+ Some(l) => match validate_digits(dtmf_tone_range[1].parse::<u8>().ok()) >+ { > Some(u) => { > // Check that the first part of the range is smaller than the second part > l < u >- }, >- None => false >+ } >+ None => false, > }, > None => false, > } >- }, >- // In this case the dtmf tone is a single tone >+ } >+ // In this case the dtmf tone is a single tone > 1 => validate_digits(dtmf_tone.parse::<u8>().ok()).is_some(), >- _ => false >+ _ => false, > }; > > if !dtmf_tone_is_ok { >- break ; >+ break; > } > } > > // Set the parsed dtmf tones or in case the parsing was insuccessfull, set it to the default "0-15" >- parameters.dtmf_tones = match dtmf_tone_is_ok{ >+ parameters.dtmf_tones = match dtmf_tone_is_ok { > true => parameter_token.to_string(), >- false => "0-15".to_string() >+ false => "0-15".to_string(), > } > } > } > > Ok(SdpAttribute::Fmtp(SdpAttributeFmtp { >- payload_type: payload_token.parse::<u8>()?, >- parameters: parameters, >- })) >+ payload_type: payload_token.parse::<u8>()?, >+ parameters: parameters, >+ })) > } > > fn parse_group(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = to_parse.split_whitespace(); > let semantics = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Group attribute is missing semantics token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Group attribute is missing semantics token".to_string(), >+ )) > } >- Some(x) => { >- match x.to_uppercase().as_ref() { >- "LS" => SdpAttributeGroupSemantic::LipSynchronization, >- "FID" => SdpAttributeGroupSemantic::FlowIdentification, >- "SRF" => SdpAttributeGroupSemantic::SingleReservationFlow, >- "ANAT" => SdpAttributeGroupSemantic::AlternateNetworkAddressType, >- "FEC" => SdpAttributeGroupSemantic::ForwardErrorCorrection, >- "DDP" => SdpAttributeGroupSemantic::DecodingDependency, >- "BUNDLE" => SdpAttributeGroupSemantic::Bundle, >- unknown @ _ => { >- return Err(SdpParserInternalError::Unsupported( >- format!("Unknown group semantic '{:?}' found", unknown) >- )) >- } >+ Some(x) => match x.to_uppercase().as_ref() { >+ "LS" => SdpAttributeGroupSemantic::LipSynchronization, >+ "FID" => SdpAttributeGroupSemantic::FlowIdentification, >+ "SRF" => SdpAttributeGroupSemantic::SingleReservationFlow, >+ "ANAT" => SdpAttributeGroupSemantic::AlternateNetworkAddressType, >+ "FEC" => SdpAttributeGroupSemantic::ForwardErrorCorrection, >+ "DDP" => SdpAttributeGroupSemantic::DecodingDependency, >+ "BUNDLE" => SdpAttributeGroupSemantic::Bundle, >+ unknown @ _ => { >+ return Err(SdpParserInternalError::Unsupported(format!( >+ "Unknown group semantic '{:?}' found", >+ unknown >+ ))) > } >- } >+ }, > }; > Ok(SdpAttribute::Group(SdpAttributeGroup { >- semantics, >- tags: tokens.map(|x| x.to_string()).collect(), >- })) >+ semantics, >+ tags: tokens.map(|x| x.to_string()).collect(), >+ })) > } > > fn parse_ice_options(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > if to_parse.is_empty() { >- return Err(SdpParserInternalError::Generic("ice-options is required to have a value" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "ice-options is required to have a value".to_string(), >+ )); > } >- Ok(SdpAttribute::IceOptions(to_parse.split_whitespace().map(|x| x.to_string()).collect())) >+ Ok(SdpAttribute::IceOptions( >+ to_parse.split_whitespace().map(|x| x.to_string()).collect(), >+ )) > } > > fn parse_imageattr_tokens(to_parse: &str, separator: char) -> Vec<String> { > let mut tokens = Vec::new(); > let mut open_braces_counter = 0; > let mut current_tokens = Vec::new(); > > for token in to_parse.split(separator) { > if token.contains("[") { >- open_braces_counter+=1; >+ open_braces_counter += 1; > } > if token.contains("]") { >- open_braces_counter-=1; >+ open_braces_counter -= 1; > } > > current_tokens.push(token.to_string()); > > if open_braces_counter == 0 { > tokens.push(current_tokens.join(&separator.to_string())); > current_tokens = Vec::new(); > } >@@ -1361,209 +1396,213 @@ fn parse_imageattr_tokens(to_parse: &str, separator: char) -> Vec<String> { > tokens > } > > fn parse_imagettr_braced_token(to_parse: &str) -> Option<&str> { > if !to_parse.ends_with("]") { > return None; > } > >- Some(&to_parse[1..to_parse.len()-1]) >+ Some(&to_parse[1..to_parse.len() - 1]) > } > >-fn parse_image_attr_xyrange(to_parse: &str) -> Result<SdpAttributeImageAttrXYRange, >- SdpParserInternalError> { >+fn parse_image_attr_xyrange( >+ to_parse: &str, >+) -> Result<SdpAttributeImageAttrXYRange, SdpParserInternalError> { > if to_parse.starts_with("[") { >- let value_tokens = parse_imagettr_braced_token(to_parse).ok_or( >- SdpParserInternalError::Generic( >- "imageattr's xyrange has no closing tag ']'".to_string() >- ) >- )?; >+ let value_tokens = >+ parse_imagettr_braced_token(to_parse).ok_or(SdpParserInternalError::Generic( >+ "imageattr's xyrange has no closing tag ']'".to_string(), >+ ))?; > > if to_parse.contains(":") { > // Range values >- let range_tokens:Vec<&str> = value_tokens.split(":").collect(); >+ let range_tokens: Vec<&str> = value_tokens.split(":").collect(); > > if range_tokens.len() == 3 { > Ok(SdpAttributeImageAttrXYRange::Range( > range_tokens[0].parse::<u32>()?, > range_tokens[2].parse::<u32>()?, > Some(range_tokens[1].parse::<u32>()?), > )) > } else if range_tokens.len() == 2 { > Ok(SdpAttributeImageAttrXYRange::Range( > range_tokens[0].parse::<u32>()?, > range_tokens[1].parse::<u32>()?, >- None >+ None, > )) > } else { > return Err(SdpParserInternalError::Generic( >- "imageattr's xyrange must contain 2 or 3 fields".to_string() >- )) >+ "imageattr's xyrange must contain 2 or 3 fields".to_string(), >+ )); > } > } else { > // Discrete values >- let values = value_tokens.split(",") >- .map(|x| x.parse::<u32>()) >- .collect::<Result<Vec<u32>, _>>()?; >+ let values = value_tokens >+ .split(",") >+ .map(|x| x.parse::<u32>()) >+ .collect::<Result<Vec<u32>, _>>()?; > > if values.len() < 2 { > return Err(SdpParserInternalError::Generic( >- "imageattr's discrete value list must have at least two elements".to_string() >- )) >+ "imageattr's discrete value list must have at least two elements".to_string(), >+ )); > } > > Ok(SdpAttributeImageAttrXYRange::DiscreteValues(values)) > } >- > } else { >- Ok(SdpAttributeImageAttrXYRange::DiscreteValues(vec![to_parse.parse::<u32>()?])) >+ Ok(SdpAttributeImageAttrXYRange::DiscreteValues(vec![ >+ to_parse.parse::<u32>()?, >+ ])) > } > } > >-fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, >- SdpParserInternalError> { >+fn parse_image_attr_set( >+ to_parse: &str, >+) -> Result<SdpAttributeImageAttrSet, SdpParserInternalError> { > let mut tokens = parse_imageattr_tokens(to_parse, ',').into_iter(); > > let x_token = tokens.next().ok_or(SdpParserInternalError::Generic( >- "imageattr set is missing the 'x=' token".to_string() >+ "imageattr set is missing the 'x=' token".to_string(), > ))?; > if !x_token.starts_with("x=") { > return Err(SdpParserInternalError::Generic( >- "The first token in an imageattr set must begin with 'x='".to_string() >- )) >+ "The first token in an imageattr set must begin with 'x='".to_string(), >+ )); > } > let x = parse_image_attr_xyrange(&x_token[2..])?; > >- > let y_token = tokens.next().ok_or(SdpParserInternalError::Generic( >- "imageattr set is missing the 'y=' token".to_string() >+ "imageattr set is missing the 'y=' token".to_string(), > ))?; > if !y_token.starts_with("y=") { > return Err(SdpParserInternalError::Generic( >- "The second token in an imageattr set must begin with 'y='".to_string() >- )) >+ "The second token in an imageattr set must begin with 'y='".to_string(), >+ )); > } > let y = parse_image_attr_xyrange(&y_token[2..])?; > > let mut sar = None; > let mut par = None; > let mut q = None; > > let parse_ps_range = |resolution_range: &str| -> Result<(f32, f32), SdpParserInternalError> { >- let minmax_pair:Vec<&str> = resolution_range.split("-").collect(); >+ let minmax_pair: Vec<&str> = resolution_range.split("-").collect(); > > if minmax_pair.len() != 2 { > return Err(SdpParserInternalError::Generic( >- "imageattr's par and sar ranges must have two components".to_string() >- )) >+ "imageattr's par and sar ranges must have two components".to_string(), >+ )); > } > > let min = minmax_pair[0].parse::<f32>()?; > let max = minmax_pair[1].parse::<f32>()?; > > if min >= max { > return Err(SdpParserInternalError::Generic( >- "In imageattr's par and sar ranges, first must be < than the second".to_string() >- )) >+ "In imageattr's par and sar ranges, first must be < than the second".to_string(), >+ )); > } > >- Ok((min,max)) >+ Ok((min, max)) > }; > > while let Some(current_token) = tokens.next() { > if current_token.starts_with("sar=") { > let value_token = &current_token[4..]; > if value_token.starts_with("[") { > let sar_values = parse_imagettr_braced_token(value_token).ok_or( > SdpParserInternalError::Generic( >- "imageattr's sar value is missing closing tag ']'".to_string() >- ) >+ "imageattr's sar value is missing closing tag ']'".to_string(), >+ ), > )?; > > if value_token.contains("-") { > // Range > let range = parse_ps_range(sar_values)?; >- sar = Some(SdpAttributeImageAttrSRange::Range(range.0,range.1)) >+ sar = Some(SdpAttributeImageAttrSRange::Range(range.0, range.1)) > } else if value_token.contains(",") { > // Discrete values >- let values = sar_values.split(",") >- .map(|x| x.parse::<f32>()) >- .collect::<Result<Vec<f32>, _>>()?; >+ let values = sar_values >+ .split(",") >+ .map(|x| x.parse::<f32>()) >+ .collect::<Result<Vec<f32>, _>>()?; > > if values.len() < 2 { > return Err(SdpParserInternalError::Generic( > "imageattr's sar discrete value list must have at least two values" >- .to_string() >- )) >+ .to_string(), >+ )); > } > > // Check that all the values are ascending > let mut last_value = 0.0; > for value in &values { > if last_value >= *value { > return Err(SdpParserInternalError::Generic( > "imageattr's sar discrete value list must contain ascending values" >- .to_string() >- )) >+ .to_string(), >+ )); > } > last_value = *value; > } > sar = Some(SdpAttributeImageAttrSRange::DiscreteValues(values)) > } > } else { >- sar = Some(SdpAttributeImageAttrSRange::DiscreteValues( >- vec![value_token.parse::<f32>()?]) >- ) >+ sar = Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![ >+ value_token.parse::<f32>()?, >+ ])) > } > } else if current_token.starts_with("par=") { > let braced_value_token = &current_token[4..]; > if !braced_value_token.starts_with("[") { > return Err(SdpParserInternalError::Generic( >- "imageattr's par value must start with '['".to_string() >- )) >+ "imageattr's par value must start with '['".to_string(), >+ )); > } > > let par_values = parse_imagettr_braced_token(braced_value_token).ok_or( > SdpParserInternalError::Generic( >- "imageattr's par value must be enclosed with ']'".to_string() >- ) >+ "imageattr's par value must be enclosed with ']'".to_string(), >+ ), > )?; > let range = parse_ps_range(par_values)?; > par = Some(SdpAttributeImageAttrPRange { > min: range.0, > max: range.1, > }) > } else if current_token.starts_with("q=") { > q = Some(current_token[2..].parse::<f32>()?); > } > } > >- Ok(SdpAttributeImageAttrSet { >- x, >- y, >- sar, >- par, >- q >- }) >+ Ok(SdpAttributeImageAttrSet { x, y, sar, par, q }) > } > >-fn parse_image_attr_set_list<I>(tokens: &mut iter::Peekable<I>) >- -> Result<SdpAttributeImageAttrSetList, SdpParserInternalError> >- where I: Iterator<Item = String> + Clone { >- let parse_set = |set_token:&str| -> Result<SdpAttributeImageAttrSet, SdpParserInternalError> { >- Ok(parse_image_attr_set(parse_imagettr_braced_token(set_token).ok_or( >- SdpParserInternalError::Generic( >- "imageattr sets must be enclosed by ']'".to_string() >- ))?)?) >+fn parse_image_attr_set_list<I>( >+ tokens: &mut iter::Peekable<I>, >+) -> Result<SdpAttributeImageAttrSetList, SdpParserInternalError> >+where >+ I: Iterator<Item = String> + Clone, >+{ >+ let parse_set = |set_token: &str| -> Result<SdpAttributeImageAttrSet, SdpParserInternalError> { >+ Ok(parse_image_attr_set( >+ parse_imagettr_braced_token(set_token).ok_or(SdpParserInternalError::Generic( >+ "imageattr sets must be enclosed by ']'".to_string(), >+ ))?, >+ )?) > }; > >- match tokens.next().ok_or(SdpParserInternalError::Generic( >- "imageattr must have a parameter set after a direction token".to_string() >- ))?.as_str() { >+ match tokens >+ .next() >+ .ok_or(SdpParserInternalError::Generic( >+ "imageattr must have a parameter set after a direction token".to_string(), >+ ))?.as_str() >+ { > "*" => Ok(SdpAttributeImageAttrSetList::Wildcard), > x => { > let mut sets = vec![parse_set(x)?]; > while let Some(set_str) = tokens.clone().peek() { > if set_str.starts_with("[") { > sets.push(parse_set(&tokens.next().unwrap())?); > } else { > break; >@@ -1573,116 +1612,121 @@ fn parse_image_attr_set_list<I>(tokens: &mut iter::Peekable<I>) > Ok(SdpAttributeImageAttrSetList::Sets(sets)) > } > } > } > > fn parse_image_attr(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = parse_imageattr_tokens(to_parse, ' ').into_iter().peekable(); > >- let pt = parse_payload_type(tokens.next().ok_or(SdpParserInternalError::Generic( >- "imageattr requires a payload token".to_string() >- ))?.as_str())?; >- let first_direction = parse_single_direction(tokens.next().ok_or( >- SdpParserInternalError::Generic( >- "imageattr's second token must be a direction token".to_string() >- ))?.as_str())?; >+ let pt = parse_payload_type( >+ tokens >+ .next() >+ .ok_or(SdpParserInternalError::Generic( >+ "imageattr requires a payload token".to_string(), >+ ))?.as_str(), >+ )?; >+ let first_direction = parse_single_direction( >+ tokens >+ .next() >+ .ok_or(SdpParserInternalError::Generic( >+ "imageattr's second token must be a direction token".to_string(), >+ ))?.as_str(), >+ )?; > > let first_set_list = parse_image_attr_set_list(&mut tokens)?; > > let mut second_set_list = SdpAttributeImageAttrSetList::Sets(Vec::new()); > > // Check if there is a second direction defined > if let Some(direction_token) = tokens.next() { > if parse_single_direction(direction_token.as_str())? == first_direction { > return Err(SdpParserInternalError::Generic( > "imageattr's second direction token must be different from the first one" >- .to_string() >- )) >+ .to_string(), >+ )); > } > > second_set_list = parse_image_attr_set_list(&mut tokens)?; > } > > if let Some(_) = tokens.next() { > return Err(SdpParserInternalError::Generic( >- "imageattr must not contain any token after the second set list".to_string() >- )) >+ "imageattr must not contain any token after the second set list".to_string(), >+ )); > } > > Ok(SdpAttribute::ImageAttr(match first_direction { >- SdpSingleDirection::Send => >- SdpAttributeImageAttr { >- pt, >- send: first_set_list, >- recv: second_set_list, >- }, >- SdpSingleDirection::Recv => >- SdpAttributeImageAttr { >- pt, >- send: second_set_list, >- recv: first_set_list, >- } >+ SdpSingleDirection::Send => SdpAttributeImageAttr { >+ pt, >+ send: first_set_list, >+ recv: second_set_list, >+ }, >+ SdpSingleDirection::Recv => SdpAttributeImageAttr { >+ pt, >+ send: second_set_list, >+ recv: first_set_list, >+ }, > })) > } > > fn parse_msid(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = to_parse.split_whitespace(); > let id = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Msid attribute is missing msid-id token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Msid attribute is missing msid-id token".to_string(), >+ )) > } > Some(x) => x.to_string(), > }; > let appdata = match tokens.next() { > None => None, > Some(x) => Some(x.to_string()), > }; > Ok(SdpAttribute::Msid(SdpAttributeMsid { id, appdata })) >- > } > > fn parse_msid_semantic(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<_> = to_parse.split_whitespace().collect(); > if tokens.len() < 1 { >- return Err(SdpParserInternalError::Generic("Msid-semantic attribute is missing msid-semantic token" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Msid-semantic attribute is missing msid-semantic token".to_string(), >+ )); > } > // TODO: Should msids be checked to ensure they are non empty? > let semantic = SdpAttributeMsidSemantic { > semantic: tokens[0].to_string(), > msids: tokens[1..].iter().map(|x| x.to_string()).collect(), > }; > Ok(SdpAttribute::MsidSemantic(semantic)) > } > > fn parse_rid(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<&str> = to_parse.splitn(3, " ").collect(); > > if tokens.len() < 2 { > return Err(SdpParserInternalError::Generic( >- "A rid attribute must at least have an id and a direction token.".to_string() >+ "A rid attribute must at least have an id and a direction token.".to_string(), > )); > } > > // Default initilize > let mut params = SdpAttributeRidParameters { > max_width: 0, > max_height: 0, > max_fps: 0, > max_fs: 0, > max_br: 0, > max_pps: 0, > unknown: Vec::new(), > }; > let mut formats: Vec<u16> = Vec::new(); > let mut depends: Vec<String> = Vec::new(); > >- > if let Some(param_token) = tokens.get(2) { > let mut parameters = param_token.split(";").peekable(); > > // The 'pt' parameter must be the first parameter if present, so it > // cannot be checked along with the other parameters below > if let Some(maybe_fmt_parameter) = parameters.clone().peek() { > if maybe_fmt_parameter.starts_with("pt=") { > let fmt_list = maybe_fmt_parameter[3..].split(","); >@@ -1691,388 +1735,403 @@ fn parse_rid(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > } > > parameters.next(); > } > } > > for param in parameters { > // TODO: Bug 1225877. Add support for params without '=' >- let param_value_pair: Vec<&str> = param.splitn(2,"=").collect(); >+ let param_value_pair: Vec<&str> = param.splitn(2, "=").collect(); > if param_value_pair.len() != 2 { > return Err(SdpParserInternalError::Generic( >- "A rid parameter needs to be of form 'param=value'".to_string() >+ "A rid parameter needs to be of form 'param=value'".to_string(), > )); > } > > match param_value_pair[0] { > "max-width" => params.max_width = param_value_pair[1].parse::<u32>()?, > "max-height" => params.max_height = param_value_pair[1].parse::<u32>()?, > "max-fps" => params.max_fps = param_value_pair[1].parse::<u32>()?, > "max-fs" => params.max_fs = param_value_pair[1].parse::<u32>()?, > "max-br" => params.max_br = param_value_pair[1].parse::<u32>()?, > "max-pps" => params.max_pps = param_value_pair[1].parse::<u32>()?, > "depends" => { > depends.extend(param_value_pair[1].split(",").map(|x| x.to_string())); >- }, >+ } > _ => params.unknown.push(param.to_string()), > } > } > } > >- Ok(SdpAttribute::Rid(SdpAttributeRid{ >+ Ok(SdpAttribute::Rid(SdpAttributeRid { > id: tokens[0].to_string(), > direction: parse_single_direction(tokens[1])?, > formats: formats, > params: params, > depends: depends, > })) > } > > fn parse_remote_candidates(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = to_parse.split_whitespace(); > let component = match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Remote-candidate attribute is missing component ID" >- .to_string(), >- )) >+ "Remote-candidate attribute is missing component ID".to_string(), >+ )) > } > Some(x) => x.parse::<u32>()?, > }; > let address = match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Remote-candidate attribute is missing connection address" >- .to_string(), >- )) >+ "Remote-candidate attribute is missing connection address".to_string(), >+ )) > } > Some(x) => parse_unicast_addr(x)?, > }; > let port = match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Remote-candidate attribute is missing port number".to_string(), >- )) >+ "Remote-candidate attribute is missing port number".to_string(), >+ )) > } > Some(x) => x.parse::<u32>()?, > }; > if port > 65535 { > return Err(SdpParserInternalError::Generic( >- "Remote-candidate port can only be a bit 16bit number".to_string(), >- )); >+ "Remote-candidate port can only be a bit 16bit number".to_string(), >+ )); > }; > Ok(SdpAttribute::RemoteCandidate(SdpAttributeRemoteCandidate { >- component, >- address, >- port, >- })) >+ component, >+ address, >+ port, >+ })) > } > > fn parse_rtpmap(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = to_parse.split_whitespace(); > let payload_type: u8 = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Rtpmap missing payload type".to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Rtpmap missing payload type".to_string(), >+ )) > } > Some(x) => { > let pt = x.parse::<u8>()?; > if pt > 127 { >- return Err(SdpParserInternalError::Generic("Rtpmap payload type must be less then 127".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Rtpmap payload type must be less then 127".to_string(), >+ )); > }; > pt > } > }; > let mut parameters = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Rtpmap missing payload type".to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Rtpmap missing payload type".to_string(), >+ )) > } > Some(x) => x.split('/'), > }; > let name = match parameters.next() { > None => { >- return Err(SdpParserInternalError::Generic("Rtpmap missing codec name".to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Rtpmap missing codec name".to_string(), >+ )) > } > Some(x) => x.to_string(), > }; > let frequency = match parameters.next() { > None => { >- return Err(SdpParserInternalError::Generic("Rtpmap missing codec name".to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Rtpmap missing codec name".to_string(), >+ )) > } > Some(x) => x.parse::<u32>()?, > }; > let mut rtpmap = SdpAttributeRtpmap::new(payload_type, name, frequency); > match parameters.next() { > Some(x) => rtpmap.set_channels(x.parse::<u32>()?), > None => (), > }; > Ok(SdpAttribute::Rtpmap(rtpmap)) > } > > fn parse_rtcp(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let mut tokens = to_parse.split_whitespace(); > let port = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Rtcp attribute is missing port number" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Rtcp attribute is missing port number".to_string(), >+ )) > } > Some(x) => x.parse::<u16>()?, > }; > let mut rtcp = SdpAttributeRtcp::new(port); > match tokens.next() { > None => (), > Some(x) => { > parse_nettype(x)?; > match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Rtcp attribute is missing address type token" >- .to_string(), >- )) >+ "Rtcp attribute is missing address type token".to_string(), >+ )) > } > Some(x) => { > let addrtype = parse_addrtype(x)?; > let addr = match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Rtcp attribute is missing ip address token" >- .to_string(), >- )) >+ "Rtcp attribute is missing ip address token".to_string(), >+ )) > } > Some(x) => { > let addr = parse_unicast_addr(x)?; > if !addrtype.same_protocol(&addr) { > return Err(SdpParserInternalError::Generic( >- "Failed to parse unicast address attribute.\ >- addrtype does not match address." >- .to_string(), >- )); >+ "Failed to parse unicast address attribute.\ >+ addrtype does not match address." >+ .to_string(), >+ )); > } > addr > } > }; > rtcp.set_addr(addr); > } > }; > } > }; > Ok(SdpAttribute::Rtcp(rtcp)) > } > > fn parse_rtcp_fb(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { >- let tokens: Vec<&str> = to_parse.splitn(4,' ').collect(); >+ let tokens: Vec<&str> = to_parse.splitn(4, ' ').collect(); > > // Parse this in advance to use it later in the parameter switch > let feedback_type = match tokens.get(1) { >- Some(x) => match x.as_ref(){ >+ Some(x) => match x.as_ref() { > "ack" => SdpAttributeRtcpFbType::Ack, > "ccm" => SdpAttributeRtcpFbType::Ccm, > "nack" => SdpAttributeRtcpFbType::Nack, > "trr-int" => SdpAttributeRtcpFbType::TrrInt, > "goog-remb" => SdpAttributeRtcpFbType::Remb, > "transport-cc" => SdpAttributeRtcpFbType::TransCC, > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb feedback type: {:?}",x).to_string() >+ format!("Unknown rtcpfb feedback type: {:?}", x).to_string(), > )) > } > }, > None => { > return Err(SdpParserInternalError::Generic( >- "Error parsing rtcpfb: no feedback type".to_string(), >- )) >+ "Error parsing rtcpfb: no feedback type".to_string(), >+ )) > } > }; > > // Parse this in advance to make the initilization block below better readable > let parameter = match &feedback_type { > &SdpAttributeRtcpFbType::Ack => match tokens.get(2) { > Some(x) => match x.as_ref() { >- "rpsi" | "app" => x.to_string(), >+ "rpsi" | "app" => x.to_string(), > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb ack parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb ack parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => { > return Err(SdpParserInternalError::Unsupported( >- format!("The rtcpfb ack feeback type needs a parameter:").to_string() >+ format!("The rtcpfb ack feeback type needs a parameter:").to_string(), > )) > } > }, > &SdpAttributeRtcpFbType::Ccm => match tokens.get(2) { > Some(x) => match x.as_ref() { >- "fir" | "tmmbr" | "tstr" | "vbcm" => x.to_string(), >+ "fir" | "tmmbr" | "tstr" | "vbcm" => x.to_string(), > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb ccm parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb ccm parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => "".to_string(), > }, > &SdpAttributeRtcpFbType::Nack => match tokens.get(2) { > Some(x) => match x.as_ref() { >- "sli" | "pli" | "rpsi" | "app" => x.to_string(), >+ "sli" | "pli" | "rpsi" | "app" => x.to_string(), > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb nack parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb nack parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => "".to_string(), > }, > &SdpAttributeRtcpFbType::TrrInt => match tokens.get(2) { > Some(x) => match x { > _ if x.parse::<u32>().is_ok() => x.to_string(), > _ => { > return Err(SdpParserInternalError::Generic( >- format!("Unknown rtcpfb trr-int parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb trr-int parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => { >- return Err(SdpParserInternalError::Generic( >- format!("The rtcpfb trr-int feedback type needs a parameter").to_string() >- )) >+ return Err(SdpParserInternalError::Generic( >+ format!("The rtcpfb trr-int feedback type needs a parameter").to_string(), >+ )) > } > }, > &SdpAttributeRtcpFbType::Remb => match tokens.get(2) { > Some(x) => match x { > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb remb parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb remb parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => "".to_string(), > }, > &SdpAttributeRtcpFbType::TransCC => match tokens.get(2) { > Some(x) => match x { > _ => { > return Err(SdpParserInternalError::Unsupported( >- format!("Unknown rtcpfb transport-cc parameter: {:?}",x).to_string() >+ format!("Unknown rtcpfb transport-cc parameter: {:?}", x).to_string(), > )) >- }, >+ } > }, > None => "".to_string(), >- } >+ }, > }; > >- > Ok(SdpAttribute::Rtcpfb(SdpAttributeRtcpFb { >- payload_type: parse_payload_type(tokens[0])?, >+ payload_type: parse_payload_type(tokens[0])?, > >- feedback_type: feedback_type, >+ feedback_type: feedback_type, > >- parameter: parameter, >+ parameter: parameter, > >- extra: match tokens.get(3) { >- Some(x) => x.to_string(), >- None => "".to_string(), >- }, >- })) >+ extra: match tokens.get(3) { >+ Some(x) => x.to_string(), >+ None => "".to_string(), >+ }, >+ })) > } > > fn parse_sctpmap(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > let tokens: Vec<&str> = to_parse.split_whitespace().collect(); > if tokens.len() != 3 { >- return Err(SdpParserInternalError::Generic("Sctpmap needs to have three tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Sctpmap needs to have three tokens".to_string(), >+ )); > } > let port = tokens[0].parse::<u16>()?; > if tokens[1].to_lowercase() != "webrtc-datachannel" { >- return Err(SdpParserInternalError::Generic("Unsupported sctpmap type token".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Unsupported sctpmap type token".to_string(), >+ )); > } > Ok(SdpAttribute::Sctpmap(SdpAttributeSctpmap { >- port, >- channels: tokens[2].parse::<u32>()?, >- })) >+ port, >+ channels: tokens[2].parse::<u32>()?, >+ })) > } > > fn parse_setup(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { >- Ok(SdpAttribute::Setup(match to_parse.to_lowercase().as_ref() { >- "active" => SdpAttributeSetup::Active, >- "actpass" => SdpAttributeSetup::Actpass, >- "holdconn" => SdpAttributeSetup::Holdconn, >- "passive" => SdpAttributeSetup::Passive, >- _ => { >- return Err(SdpParserInternalError::Generic( >- "Unsupported setup value".to_string(), >- )) >- } >- })) >+ Ok(SdpAttribute::Setup( >+ match to_parse.to_lowercase().as_ref() { >+ "active" => SdpAttributeSetup::Active, >+ "actpass" => SdpAttributeSetup::Actpass, >+ "holdconn" => SdpAttributeSetup::Holdconn, >+ "passive" => SdpAttributeSetup::Passive, >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "Unsupported setup value".to_string(), >+ )) >+ } >+ }, >+ )) > } > >-fn parse_simulcast_version_list(to_parse: &str) -> Result<Vec<SdpAttributeSimulcastVersion>, >- SdpParserInternalError> { >+fn parse_simulcast_version_list( >+ to_parse: &str, >+) -> Result<Vec<SdpAttributeSimulcastVersion>, SdpParserInternalError> { > let make_version_list = |to_parse: &str| { >- to_parse.split(';').map(SdpAttributeSimulcastVersion::new).collect() >+ to_parse >+ .split(';') >+ .map(SdpAttributeSimulcastVersion::new) >+ .collect() > }; > if to_parse.contains("=") { >- let mut descriptor_versionlist_pair = to_parse.splitn(2,"="); >- match descriptor_versionlist_pair.next().unwrap() { >- // TODO Bug 1470568 >- "rid" => Ok(make_version_list(descriptor_versionlist_pair.next().unwrap())), >- descriptor @ _ => { >- return Err(SdpParserInternalError::Generic( >- format!("Simulcast attribute has unknown list descriptor '{:?}'", >- descriptor) >- .to_string() >- )) >- } >- } >+ let mut descriptor_versionlist_pair = to_parse.splitn(2, "="); >+ match descriptor_versionlist_pair.next().unwrap() { >+ // TODO Bug 1470568 >+ "rid" => Ok(make_version_list( >+ descriptor_versionlist_pair.next().unwrap(), >+ )), >+ descriptor @ _ => { >+ return Err(SdpParserInternalError::Generic( >+ format!( >+ "Simulcast attribute has unknown list descriptor '{:?}'", >+ descriptor >+ ).to_string(), >+ )) >+ } >+ } > } else { >- Ok(make_version_list(to_parse)) >+ Ok(make_version_list(to_parse)) > } > } > > fn parse_simulcast(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { > // TODO: Bug 1225877: Stop accepting all kinds of whitespace here, and only accept SP > let mut tokens = to_parse.trim().split_whitespace(); > let first_direction = match tokens.next() { > Some(x) => parse_single_direction(x)?, > None => { > return Err(SdpParserInternalError::Generic( >- "Simulcast attribute is missing send/recv value".to_string(), >- )) >+ "Simulcast attribute is missing send/recv value".to_string(), >+ )) > } > }; > > let first_version_list = match tokens.next() { >- Some(x) => { >- parse_simulcast_version_list(x)? >- }, >+ Some(x) => parse_simulcast_version_list(x)?, > None => { > return Err(SdpParserInternalError::Generic( >- "Simulcast attribute must have an alternatives list after the direction token" >+ "Simulcast attribute must have an alternatives list after the direction token" > .to_string(), > )); > } > }; > > let mut second_version_list = Vec::new(); > if let Some(x) = tokens.next() { > if parse_single_direction(x)? == first_direction { > return Err(SdpParserInternalError::Generic( >- "Simulcast attribute has defined two times the same direction".to_string() >+ "Simulcast attribute has defined two times the same direction".to_string(), > )); > } > > second_version_list = match tokens.next() { >- Some(x) => { >- parse_simulcast_version_list(x)? >- }, >+ Some(x) => parse_simulcast_version_list(x)?, > None => { > return Err(SdpParserInternalError::Generic( >- format!("{:?}{:?}", >- "Simulcast has defined a second direction but", >- "no second list of simulcast stream versions") >- .to_string() >+ format!( >+ "{:?}{:?}", >+ "Simulcast has defined a second direction but", >+ "no second list of simulcast stream versions" >+ ).to_string(), > )); > } > } > } > > Ok(SdpAttribute::Simulcast(match first_direction { > SdpSingleDirection::Send => SdpAttributeSimulcast { > send: first_version_list, >@@ -2081,48 +2140,48 @@ fn parse_simulcast(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalErro > SdpSingleDirection::Recv => SdpAttributeSimulcast { > send: second_version_list, > receive: first_version_list, > }, > })) > } > > fn parse_ssrc(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> { >- let mut tokens = to_parse.splitn(2,' '); >+ let mut tokens = to_parse.splitn(2, ' '); > let ssrc_id = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Ssrc attribute is missing ssrc-id value" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Ssrc attribute is missing ssrc-id value".to_string(), >+ )) > } > Some(x) => x.parse::<u32>()?, > }; > let mut ssrc = SdpAttributeSsrc::new(ssrc_id); > match tokens.next() { > None => (), > Some(x) => ssrc.set_attribute(x), > }; > Ok(SdpAttribute::Ssrc(ssrc)) > } > > pub fn parse_attribute(value: &str) -> Result<SdpType, SdpParserInternalError> { > Ok(SdpType::Attribute(value.trim().parse()?)) > } > >- > #[cfg(test)] > macro_rules! make_check_parse { > ($attr_type:ty, $attr_kind:path) => { > |attr_str: &str| -> $attr_type { > if let Ok(SdpType::Attribute($attr_kind(attr))) = parse_attribute(attr_str) { > attr > } else { > unreachable!(); > } > } >- } >+ }; > } > > #[test] > fn test_parse_attribute_candidate() { > let check_parse = make_check_parse!(SdpAttributeCandidate, SdpAttribute::Candidate); > > let check_parse_and_serialize = |attr_str| { > let parsed = check_parse(attr_str); >@@ -2131,53 +2190,75 @@ fn test_parse_attribute_candidate() { > > check_parse_and_serialize("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ host"); > check_parse_and_serialize("candidate:foo 1 UDP 2122252543 172.16.156.106 49760 typ host"); > check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host"); > check_parse_and_serialize("candidate:0 1 TCP 2122252543 ::1 49760 typ host"); > check_parse_and_serialize("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ srflx"); > check_parse_and_serialize("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ prflx"); > check_parse_and_serialize("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ relay"); >- check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype active"); >- check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype passive"); >- check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype so"); >- check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host ufrag foobar"); >- check_parse_and_serialize("candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host network-cost 50"); >+ check_parse_and_serialize( >+ "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype active", >+ ); >+ check_parse_and_serialize( >+ "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype passive", >+ ); >+ check_parse_and_serialize( >+ "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host tcptype so", >+ ); >+ check_parse_and_serialize( >+ "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host ufrag foobar", >+ ); >+ check_parse_and_serialize( >+ "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host network-cost 50", >+ ); > check_parse_and_serialize("candidate:1 1 UDP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 generation 0"); >- check_parse_and_serialize("candidate:1 1 UDP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665"); >+ check_parse_and_serialize( >+ "candidate:1 1 UDP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665", >+ ); > check_parse_and_serialize("candidate:1 1 TCP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 tcptype passive"); > check_parse_and_serialize("candidate:1 1 TCP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 tcptype passive generation 1"); > check_parse_and_serialize("candidate:1 1 TCP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 tcptype passive generation 1 ufrag +DGd"); > check_parse_and_serialize("candidate:1 1 TCP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 tcptype passive generation 1 ufrag +DGd network-cost 1"); > > let candidate = check_parse("candidate:1 1 TCP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 tcptype passive generation 1 ufrag +DGd network-cost 1"); > assert_eq!(candidate.foundation, "1".to_string()); > assert_eq!(candidate.component, 1); > assert_eq!(candidate.transport, SdpAttributeCandidateTransport::Tcp); > assert_eq!(candidate.priority, 1685987071); >- assert_eq!(candidate.address, IpAddr::from_str("24.23.204.141").unwrap()); >+ assert_eq!( >+ candidate.address, >+ IpAddr::from_str("24.23.204.141").unwrap() >+ ); > assert_eq!(candidate.port, 54609); > assert_eq!(candidate.c_type, SdpAttributeCandidateType::Srflx); >- assert_eq!(candidate.raddr, Some(IpAddr::from_str("192.168.1.4").unwrap())); >+ assert_eq!( >+ candidate.raddr, >+ Some(IpAddr::from_str("192.168.1.4").unwrap()) >+ ); > assert_eq!(candidate.rport, Some(61665)); >- assert_eq!(candidate.tcp_type, Some(SdpAttributeCandidateTcpType::Passive)); >+ assert_eq!( >+ candidate.tcp_type, >+ Some(SdpAttributeCandidateTcpType::Passive) >+ ); > assert_eq!(candidate.generation, Some(1)); > assert_eq!(candidate.ufrag, Some("+DGd".to_string())); > assert_eq!(candidate.networkcost, Some(1)); > >- > assert!(parse_attribute("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ").is_err()); >- assert!(parse_attribute("candidate:0 foo UDP 2122252543 172.16.156.106 49760 typ host") >- .is_err()); >+ assert!( >+ parse_attribute("candidate:0 foo UDP 2122252543 172.16.156.106 49760 typ host").is_err() >+ ); > assert!(parse_attribute("candidate:0 1 FOO 2122252543 172.16.156.106 49760 typ host").is_err()); > assert!(parse_attribute("candidate:0 1 UDP foo 172.16.156.106 49760 typ host").is_err()); > assert!(parse_attribute("candidate:0 1 UDP 2122252543 172.16.156 49760 typ host").is_err()); > assert!(parse_attribute("candidate:0 1 UDP 2122252543 172.16.156.106 70000 typ host").is_err()); >- assert!(parse_attribute("candidate:0 1 UDP 2122252543 172.16.156.106 49760 type host") >- .is_err()); >+ assert!( >+ parse_attribute("candidate:0 1 UDP 2122252543 172.16.156.106 49760 type host").is_err() >+ ); > assert!(parse_attribute("candidate:0 1 UDP 2122252543 172.16.156.106 49760 typ fost").is_err()); > // FIXME this should fail without the extra 'foobar' at the end > assert!( > parse_attribute( > "candidate:0 1 TCP 2122252543 172.16.156.106 49760 typ host unsupported foobar" > ).is_err() > ); > assert!(parse_attribute("candidate:1 1 UDP 1685987071 24.23.204.141 54609 typ srflx raddr 192.168.1.4 rport 61665 generation B").is_err()); >@@ -2211,94 +2292,172 @@ fn test_parse_dtls_message() { > x > } else { > unreachable!(); > } > }; > > assert!(parse_attribute("dtls-message:client SGVsbG8gV29ybGQ=").is_ok()); > assert!(parse_attribute("dtls-message:server SGVsbG8gV29ybGQ=").is_ok()); >- assert!(parse_attribute("dtls-message:client IGlzdCBl/W4gUeiBtaXQg+JSB1bmQCAkJJkSNEQ=").is_ok()); >- assert!(parse_attribute("dtls-message:server IGlzdCBl/W4gUeiBtaXQg+JSB1bmQCAkJJkSNEQ=").is_ok()); >+ assert!( >+ parse_attribute("dtls-message:client IGlzdCBl/W4gUeiBtaXQg+JSB1bmQCAkJJkSNEQ=").is_ok() >+ ); >+ assert!( >+ parse_attribute("dtls-message:server IGlzdCBl/W4gUeiBtaXQg+JSB1bmQCAkJJkSNEQ=").is_ok() >+ ); > > let mut dtls_message = check_parse("dtls-message:client SGVsbG8gV29ybGQ="); > match dtls_message { > SdpAttributeDtlsMessage::Client(x) => { > assert_eq!(x, "SGVsbG8gV29ybGQ="); >- }, >- _ => { unreachable!(); } >+ } >+ _ => { >+ unreachable!(); >+ } > } > > dtls_message = check_parse("dtls-message:server SGVsbG8gV29ybGQ="); > match dtls_message { > SdpAttributeDtlsMessage::Server(x) => { > assert_eq!(x, "SGVsbG8gV29ybGQ="); >- }, >- _ => { unreachable!(); } >+ } >+ _ => { >+ unreachable!(); >+ } > } > >- > assert!(parse_attribute("dtls-message:client").is_err()); > assert!(parse_attribute("dtls-message:server").is_err()); > } > > #[test] > fn test_parse_attribute_end_of_candidates() { > assert!(parse_attribute("end-of-candidates").is_ok()); > assert!(parse_attribute("end-of-candidates foobar").is_err()); > } > > #[test] > fn test_parse_attribute_extmap() { >- assert!(parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level") >- .is_ok()); >- assert!(parse_attribute("extmap:2/sendrecv urn:ietf:params:rtp-hdrext:ssrc-audio-level") >- .is_ok()); >- assert!(parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time") >- .is_ok()); >+ assert!( >+ parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level").is_ok() >+ ); >+ assert!( >+ parse_attribute("extmap:2/sendrecv urn:ietf:params:rtp-hdrext:ssrc-audio-level").is_ok() >+ ); >+ assert!( >+ parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time") >+ .is_ok() >+ ); > >- assert!(parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time ext_attributes") >- .is_ok()); >+ assert!( >+ parse_attribute( >+ "extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time ext_attributes" >+ ).is_ok() >+ ); > >- assert!(parse_attribute("extmap:a/sendrecv urn:ietf:params:rtp-hdrext:ssrc-audio-level") >- .is_err()); >- assert!(parse_attribute("extmap:4/unsupported urn:ietf:params:rtp-hdrext:ssrc-audio-level") >- .is_err()); >+ assert!( >+ parse_attribute("extmap:a/sendrecv urn:ietf:params:rtp-hdrext:ssrc-audio-level").is_err() >+ ); >+ assert!( >+ parse_attribute("extmap:4/unsupported urn:ietf:params:rtp-hdrext:ssrc-audio-level") >+ .is_err() >+ ); > >- let mut bad_char = String::from("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time ",); >+ let mut bad_char = >+ String::from("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time "); > bad_char.push(0x00 as char); > assert!(parse_attribute(&bad_char).is_err()); > } > > #[test] > fn test_parse_attribute_fingerprint() { >- assert!(parse_attribute("fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_ok()); >- assert!(parse_attribute("fingerprint:sha-224 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >- 27:97:EB:0B:23:73:AC:BC").is_ok()); >- assert!(parse_attribute("fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >- 27:97:EB:0B:23:73:AC:BC:CD:34:D1:62").is_ok()); >- assert!(parse_attribute("fingerprint:sha-384 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >- 27:97:EB:0B:23:73:AC:BC:CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:\ >- 27:97:EB:0B:23:73:AC:BC").is_ok()); >- assert!(parse_attribute("fingerprint:sha-512 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >- 97:EB:0B:23:73:AC:BC:CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:\ >- EB:0B:23:73:AC:BC:27:97:EB:0B:23:73:AC:BC:27:97:EB:0B:23:73:\ >- BC:EB:0B:23").is_ok()); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_ok() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-224 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >+ 27:97:EB:0B:23:73:AC:BC" >+ ).is_ok() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-256 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >+ 27:97:EB:0B:23:73:AC:BC:CD:34:D1:62" >+ ).is_ok() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-384 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >+ 27:97:EB:0B:23:73:AC:BC:CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:\ >+ 27:97:EB:0B:23:73:AC:BC" >+ ).is_ok() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-512 CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC:\ >+ 97:EB:0B:23:73:AC:BC:CD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:\ >+ EB:0B:23:73:AC:BC:27:97:EB:0B:23:73:AC:BC:27:97:EB:0B:23:73:\ >+ BC:EB:0B:23" >+ ).is_ok() >+ ); > >- assert!(parse_attribute("fingerprint:sha-1 CX:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CDA:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CX:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC").is_err()); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CX:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CDA:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CX:34:D1:62:16:95:7B:B7:EB:74:E1:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); > >- assert!(parse_attribute("fingerprint:sha-1 0xCD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD:0x34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD::D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD:0000A:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_err()); >- assert!(parse_attribute("fingerprint:sha-1 CD:B:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC").is_err()); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 0xCD:34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:0x34:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD::D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:0000A:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); >+ assert!( >+ parse_attribute( >+ "fingerprint:sha-1 CD:B:D1:62:16:95:7B:B7:EB:74:E2:39:27:97:EB:0B:23:73:AC:BC" >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_attribute_fmtp() { > assert!(parse_attribute("fmtp:109 maxplaybackrate=48000;stereo=1;useinbandfec=1").is_ok()); > assert!(parse_attribute("fmtp:66 0-15").is_ok()); > assert!(parse_attribute("fmtp:109 0-15,66").is_ok()); > assert!(parse_attribute("fmtp:66 111/115").is_ok()); >@@ -2316,17 +2475,17 @@ fn test_parse_attribute_fmtp() { > fn test_parse_attribute_group() { > assert!(parse_attribute("group:LS").is_ok()); > assert!(parse_attribute("group:LS 1 2").is_ok()); > assert!(parse_attribute("group:BUNDLE sdparta_0 sdparta_1 sdparta_2").is_ok()); > > assert!(parse_attribute("group:").is_err()); > assert!(match parse_attribute("group:NEVER_SUPPORTED_SEMANTICS") { > Err(SdpParserInternalError::Unsupported(_)) => true, >- _ => false >+ _ => false, > }) > } > > #[test] > fn test_parse_attribute_bundle_only() { > assert!(parse_attribute("bundle-only").is_ok()); > assert!(parse_attribute("bundle-only foobar").is_err()); > } >@@ -2380,74 +2539,120 @@ fn test_parse_attribute_imageattr() { > x > } else { > unreachable!(); > } > }; > > assert!(parse_attribute("imageattr:120 send * recv *").is_ok()); > assert!(parse_attribute("imageattr:99 send [x=320,y=240] recv [x=320,y=240]").is_ok()); >- assert!(parse_attribute("imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]").is_ok()); >+ assert!( >+ parse_attribute( >+ "imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]" >+ ).is_ok() >+ ); > assert!(parse_attribute("imageattr:97 recv [x=800,y=640,sar=1.1] send [x=330,y=250]").is_ok()); > assert!(parse_attribute("imageattr:97 send [x=[480:16:800],y=[320:16:640],par=[1.2-1.3],q=0.6] [x=[176:8:208],y=[144:8:176],par=[1.2-1.3]] recv *").is_ok()); > >- let mut imageattr = check_parse("imageattr:* recv [x=800,y=[50,80,30],sar=1.1] send [x=330,y=250,sar=[1.1,1.3,1.9],q=0.1]"); >+ let mut imageattr = check_parse( >+ "imageattr:* recv [x=800,y=[50,80,30],sar=1.1] send [x=330,y=250,sar=[1.1,1.3,1.9],q=0.1]", >+ ); > assert_eq!(imageattr.pt, SdpAttributePayloadType::Wildcard); > match imageattr.recv { > SdpAttributeImageAttrSetList::Sets(sets) => { > assert_eq!(sets.len(), 1); > > let set = &sets[0]; >- assert_eq!(set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![800])); >- assert_eq!(set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![50,80,30])); >+ assert_eq!( >+ set.x, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![800]) >+ ); >+ assert_eq!( >+ set.y, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![50, 80, 30]) >+ ); > assert_eq!(set.par, None); >- assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![1.1]))); >+ assert_eq!( >+ set.sar, >+ Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![1.1])) >+ ); > assert_eq!(set.q, None); >- >- }, >- _ => { unreachable!(); } >+ } >+ _ => { >+ unreachable!(); >+ } > } > match imageattr.send { > SdpAttributeImageAttrSetList::Sets(sets) => { > assert_eq!(sets.len(), 1); > > let set = &sets[0]; >- assert_eq!(set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![330])); >- assert_eq!(set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![250])); >+ assert_eq!( >+ set.x, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![330]) >+ ); >+ assert_eq!( >+ set.y, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![250]) >+ ); > assert_eq!(set.par, None); >- assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![1.1,1.3,1.9]))); >+ assert_eq!( >+ set.sar, >+ Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![ >+ 1.1, 1.3, 1.9 >+ ])) >+ ); > assert_eq!(set.q, Some(0.1)); >- }, >- _ => { unreachable!(); } >+ } >+ _ => { >+ unreachable!(); >+ } > } > > imageattr = check_parse("imageattr:97 send [x=[480:16:800],y=[100,200,300],par=[1.2-1.3],q=0.6] [x=1080,y=[144:176],sar=[0.5-0.7]] recv *"); > assert_eq!(imageattr.pt, SdpAttributePayloadType::PayloadType(97)); > match imageattr.send { > SdpAttributeImageAttrSetList::Sets(sets) => { > assert_eq!(sets.len(), 2); > > let first_set = &sets[0]; >- assert_eq!(first_set.x, SdpAttributeImageAttrXYRange::Range(480, 800, Some(16))); >- assert_eq!(first_set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![100, 200, 300])); >- assert_eq!(first_set.par, Some(SdpAttributeImageAttrPRange { >- min: 1.2, >- max: 1.3 >- })); >+ assert_eq!( >+ first_set.x, >+ SdpAttributeImageAttrXYRange::Range(480, 800, Some(16)) >+ ); >+ assert_eq!( >+ first_set.y, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![100, 200, 300]) >+ ); >+ assert_eq!( >+ first_set.par, >+ Some(SdpAttributeImageAttrPRange { min: 1.2, max: 1.3 }) >+ ); > assert_eq!(first_set.sar, None); > assert_eq!(first_set.q, Some(0.6)); > > let second_set = &sets[1]; >- assert_eq!(second_set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![1080])); >- assert_eq!(second_set.y, SdpAttributeImageAttrXYRange::Range(144, 176, None)); >+ assert_eq!( >+ second_set.x, >+ SdpAttributeImageAttrXYRange::DiscreteValues(vec![1080]) >+ ); >+ assert_eq!( >+ second_set.y, >+ SdpAttributeImageAttrXYRange::Range(144, 176, None) >+ ); > assert_eq!(second_set.par, None); >- assert_eq!(second_set.sar, Some(SdpAttributeImageAttrSRange::Range(0.5, 0.7))); >+ assert_eq!( >+ second_set.sar, >+ Some(SdpAttributeImageAttrSRange::Range(0.5, 0.7)) >+ ); > assert_eq!(second_set.q, None); >- }, >- _ => { unreachable!(); } >+ } >+ _ => { >+ unreachable!(); >+ } > } > assert_eq!(imageattr.recv, SdpAttributeImageAttrSetList::Wildcard); > > assert!(parse_attribute("imageattr:99 send [x=320,y=240]").is_ok()); > assert!(parse_attribute("imageattr:100 recv [x=320,y=240]").is_ok()); > assert!(parse_attribute("imageattr:97 recv [x=800,y=640,sar=1.1,foo=[123,456],q=0.5] send [x=330,y=250,bar=foo,sar=[20-40]]").is_ok()); > assert!(parse_attribute("imageattr:97 recv [x=800,y=640,sar=1.1,foo=abc xyz,q=0.5] send [x=330,y=250,bar=foo,sar=[20-40]]").is_ok()); > >@@ -2508,52 +2713,52 @@ fn test_parse_attribute_msid_semantics() { > fn test_parse_attribute_ptime() { > assert!(parse_attribute("ptime:30").is_ok()); > > assert!(parse_attribute("ptime:").is_err()); > } > > #[test] > fn test_parse_attribute_rid() { >- > let check_parse = |x| -> SdpAttributeRid { > if let Ok(SdpType::Attribute(SdpAttribute::Rid(x))) = parse_attribute(x) { > x > } else { > unreachable!(); > } > }; > > // assert!(parse_attribute("rid:foo send").is_ok()); > let mut rid = check_parse("rid:foo send"); > assert_eq!(rid.id, "foo"); > assert_eq!(rid.direction, SdpSingleDirection::Send); > >- > // assert!(parse_attribute("rid:110 send pt=9").is_ok()); > rid = check_parse("rid:110 send pt=9"); > assert_eq!(rid.id, "110"); > assert_eq!(rid.direction, SdpSingleDirection::Send); > assert_eq!(rid.formats, vec![9]); > > assert!(parse_attribute("rid:foo send pt=10").is_ok()); > assert!(parse_attribute("rid:110 send pt=9,10").is_ok()); > assert!(parse_attribute("rid:110 send pt=9,10;max-fs=10").is_ok()); > assert!(parse_attribute("rid:110 send pt=9,10;max-width=10;depends=1,2,3").is_ok()); > > // assert!(parse_attribute("rid:110 send pt=9,10;max-fs=10;UNKNOWN=100;depends=1,2,3").is_ok()); > rid = check_parse("rid:110 send pt=9,10;max-fs=10;UNKNOWN=100;depends=1,2,3"); > assert_eq!(rid.id, "110"); > assert_eq!(rid.direction, SdpSingleDirection::Send); >- assert_eq!(rid.formats, vec![9,10]); >+ assert_eq!(rid.formats, vec![9, 10]); > assert_eq!(rid.params.max_fs, 10); > assert_eq!(rid.params.unknown, vec!["UNKNOWN=100"]); >- assert_eq!(rid.depends, vec!["1","2","3"]); >+ assert_eq!(rid.depends, vec!["1", "2", "3"]); > >- assert!(parse_attribute("rid:110 send pt=9, 10;max-fs=10;UNKNOWN=100; depends=1, 2, 3").is_ok()); >+ assert!( >+ parse_attribute("rid:110 send pt=9, 10;max-fs=10;UNKNOWN=100; depends=1, 2, 3").is_ok() >+ ); > assert!(parse_attribute("rid:110 send max-fs=10").is_ok()); > assert!(parse_attribute("rid:110 recv max-width=1920;max-height=1080").is_ok()); > > // assert!(parse_attribute("rid:110 recv max-fps=42;max-fs=10;max-br=3;max-pps=1000").is_ok()); > rid = check_parse("rid:110 recv max-fps=42;max-fs=10;max-br=3;max-pps=1000"); > assert_eq!(rid.id, "110"); > assert_eq!(rid.direction, SdpSingleDirection::Recv); > assert_eq!(rid.params.max_fps, 42); >@@ -2725,18 +2930,19 @@ fn test_parse_attribute_simulcast() { > // old draft 03 notation used by Firefox 55 > assert!(parse_attribute("simulcast: send foo=8;10").is_err()); > } > > #[test] > fn test_parse_attribute_ssrc() { > assert!(parse_attribute("ssrc:2655508255").is_ok()); > assert!(parse_attribute("ssrc:2655508255 foo").is_ok()); >- assert!(parse_attribute("ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}") >- .is_ok()); >+ assert!( >+ parse_attribute("ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}").is_ok() >+ ); > assert!(parse_attribute("ssrc:2082260239 msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 315b086a-5cb6-4221-89de-caf0b038c79d") > .is_ok()); > > assert!(parse_attribute("ssrc:").is_err()); > assert!(parse_attribute("ssrc:foo").is_err()); > } > > #[test] >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/bin/file_parser.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/bin/file_parser.rs >index 04ba61c81c9d..81caa1c31265 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/bin/file_parser.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/bin/file_parser.rs >@@ -1,35 +1,31 @@ >+use std::env; > use std::error::Error; >-use std::io::prelude::*; > use std::fs::File; >+use std::io::prelude::*; > use std::path::Path; >-use std::env; > extern crate rsdparsa; > > fn main() { > let filename = match env::args().nth(1) { > None => { > println!("Missing file name argument!"); > return; >- }, >+ } > Some(x) => x, > }; > let path = Path::new(filename.as_str()); > let display = path.display(); > > let mut file = match File::open(&path) { >- Err(why) => panic!("Failed to open {}: {}", >- display, >- why.description()), >- Ok(file) => file >+ Err(why) => panic!("Failed to open {}: {}", display, why.description()), >+ Ok(file) => file, > }; > > let mut s = String::new(); > match file.read_to_string(&mut s) { >- Err(why) => panic!("couldn't read {}: {}", >- display, >- why.description()), >- Ok(s) => s >+ Err(why) => panic!("couldn't read {}: {}", display, why.description()), >+ Ok(s) => s, > }; > > rsdparsa::parse_sdp(&s, true).is_ok(); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs >index 9adea091f49d..66b71ff735b5 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/error.rs >@@ -1,17 +1,16 @@ >-use std::num::ParseIntError; >-use std::num::ParseFloatError; >-use std::net::AddrParseError; >-use std::fmt; >+#[cfg(feature = "serialize")] >+use serde::ser::{Serialize, SerializeStruct, Serializer}; > use std::error; > use std::error::Error; >-#[cfg(feature = "serialize")] >-use serde::ser::{Serializer, Serialize, SerializeStruct}; >- >+use std::fmt; >+use std::net::AddrParseError; >+use std::num::ParseFloatError; >+use std::num::ParseIntError; > > #[derive(Debug, Clone)] > pub enum SdpParserInternalError { > Generic(String), > Unsupported(String), > Integer(ParseIntError), > Float(ParseFloatError), > Address(AddrParseError), >@@ -37,18 +36,18 @@ impl fmt::Display for SdpParserInternalError { > } > } > } > } > > impl error::Error for SdpParserInternalError { > fn description(&self) -> &str { > match *self { >- SdpParserInternalError::Generic(ref message) | >- SdpParserInternalError::Unsupported(ref message) => message, >+ SdpParserInternalError::Generic(ref message) >+ | SdpParserInternalError::Unsupported(ref message) => message, > SdpParserInternalError::Integer(ref error) => error.description(), > SdpParserInternalError::Float(ref error) => error.description(), > SdpParserInternalError::Address(ref error) => error.description(), > } > } > > fn cause(&self) -> Option<&error::Error> { > match *self { >@@ -59,152 +58,179 @@ impl error::Error for SdpParserInternalError { > _ => None, > } > } > } > > #[test] > fn test_sdp_parser_internal_error_generic() { > let generic = SdpParserInternalError::Generic("generic message".to_string()); >- assert_eq!(format!("{}", generic), >- "Generic parsing error: generic message"); >+ assert_eq!( >+ format!("{}", generic), >+ "Generic parsing error: generic message" >+ ); > assert_eq!(generic.description(), "generic message"); > assert!(generic.cause().is_none()); > } > > #[test] > fn test_sdp_parser_internal_error_unsupported() { >- let unsupported = SdpParserInternalError::Unsupported("unsupported internal message" >- .to_string()); >- assert_eq!(format!("{}", unsupported), >- "Unsupported parsing error: unsupported internal message"); >+ let unsupported = >+ SdpParserInternalError::Unsupported("unsupported internal message".to_string()); >+ assert_eq!( >+ format!("{}", unsupported), >+ "Unsupported parsing error: unsupported internal message" >+ ); > assert_eq!(unsupported.description(), "unsupported internal message"); > assert!(unsupported.cause().is_none()); > } > > #[test] > fn test_sdp_parser_internal_error_integer() { > let v = "12a"; > let integer = v.parse::<u64>(); > assert!(integer.is_err()); > let int_err = SdpParserInternalError::Integer(integer.err().unwrap()); >- assert_eq!(format!("{}", int_err), >- "Integer parsing error: invalid digit found in string"); >+ assert_eq!( >+ format!("{}", int_err), >+ "Integer parsing error: invalid digit found in string" >+ ); > assert_eq!(int_err.description(), "invalid digit found in string"); > assert!(!int_err.cause().is_none()); > } > > #[test] > fn test_sdp_parser_internal_error_address() { > let v = "127.0.0.a"; >- use std::str::FromStr; > use std::net::IpAddr; >+ use std::str::FromStr; > let addr = IpAddr::from_str(v); > assert!(addr.is_err()); > let addr_err = SdpParserInternalError::Address(addr.err().unwrap()); >- assert_eq!(format!("{}", addr_err), >- "IP address parsing error: invalid IP address syntax"); >+ assert_eq!( >+ format!("{}", addr_err), >+ "IP address parsing error: invalid IP address syntax" >+ ); > assert_eq!(addr_err.description(), "invalid IP address syntax"); > assert!(!addr_err.cause().is_none()); > } > > #[derive(Debug, Clone)] > pub enum SdpParserError { > Line { > error: SdpParserInternalError, > line: String, > line_number: usize, > }, > Unsupported { > error: SdpParserInternalError, > line: String, > line_number: usize, > }, >- Sequence { message: String, line_number: usize }, >+ Sequence { >+ message: String, >+ line_number: usize, >+ }, > } > > #[cfg(feature = "serialize")] > impl Serialize for SdpParserError { >- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer { >- let mut state = serializer.serialize_struct("error", match self { >- &SdpParserError::Sequence{..} => 3, >- _ => 4 >- })?; >+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> >+ where >+ S: Serializer, >+ { >+ let mut state = serializer.serialize_struct( >+ "error", >+ match self { >+ &SdpParserError::Sequence { .. } => 3, >+ _ => 4, >+ }, >+ )?; > match self { >- &SdpParserError::Line {ref error, ref line, ..} => { >+ &SdpParserError::Line { >+ ref error, >+ ref line, >+ .. >+ } => { > state.serialize_field("type", "Line")?; > state.serialize_field("message", &format!("{}", error))?; > state.serialize_field("line", &line)? >- }, >- &SdpParserError::Unsupported {ref error, ref line, ..} => { >+ } >+ &SdpParserError::Unsupported { >+ ref error, >+ ref line, >+ .. >+ } => { > state.serialize_field("type", "Unsupported")?; > state.serialize_field("message", &format!("{}", error))?; > state.serialize_field("line", &line)? >- }, >- &SdpParserError::Sequence {ref message, ..} => { >+ } >+ &SdpParserError::Sequence { ref message, .. } => { > state.serialize_field("type", "Sequence")?; > state.serialize_field("message", &message)?; > } > }; >- state.serialize_field("line_number", &match self { >- &SdpParserError::Line {line_number, ..} => line_number, >- &SdpParserError::Unsupported {line_number, ..} => line_number, >- &SdpParserError::Sequence {line_number, ..} => line_number, >- })?; >+ state.serialize_field( >+ "line_number", >+ &match self { >+ &SdpParserError::Line { line_number, .. } => line_number, >+ &SdpParserError::Unsupported { line_number, .. } => line_number, >+ &SdpParserError::Sequence { line_number, .. } => line_number, >+ }, >+ )?; > state.end() > } > } > > impl fmt::Display for SdpParserError { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > match *self { > SdpParserError::Line { > ref error, > ref line, > ref line_number, >- } => { >- write!(f, >- "Line error: {} in line({}): {}", >- error.description(), >- line_number, >- line) >- } >+ } => write!( >+ f, >+ "Line error: {} in line({}): {}", >+ error.description(), >+ line_number, >+ line >+ ), > SdpParserError::Unsupported { > ref error, > ref line, > ref line_number, >- } => { >- write!(f, >- "Unsupported: {} in line({}): {}", >- error.description(), >- line_number, >- line) >- } >+ } => write!( >+ f, >+ "Unsupported: {} in line({}): {}", >+ error.description(), >+ line_number, >+ line >+ ), > SdpParserError::Sequence { > ref message, > ref line_number, > } => write!(f, "Sequence error in line({}): {}", line_number, message), > } > } > } > >- > impl error::Error for SdpParserError { > fn description(&self) -> &str { > match *self { >- SdpParserError::Line { ref error, .. } | >- SdpParserError::Unsupported { ref error, .. } => error.description(), >+ SdpParserError::Line { ref error, .. } >+ | SdpParserError::Unsupported { ref error, .. } => error.description(), > SdpParserError::Sequence { ref message, .. } => message, > } > } > > fn cause(&self) -> Option<&error::Error> { > match *self { >- SdpParserError::Line { ref error, .. } | >- SdpParserError::Unsupported { ref error, .. } => Some(error), >+ SdpParserError::Line { ref error, .. } >+ | SdpParserError::Unsupported { ref error, .. } => Some(error), > // Can't tell much more about our internal errors > _ => None, > } > } > } > > impl From<ParseIntError> for SdpParserInternalError { > fn from(err: ParseIntError) -> SdpParserInternalError { >@@ -226,38 +252,44 @@ impl From<ParseFloatError> for SdpParserInternalError { > > #[test] > fn test_sdp_parser_error_line() { > let line1 = SdpParserError::Line { > error: SdpParserInternalError::Generic("test message".to_string()), > line: "test line".to_string(), > line_number: 13, > }; >- assert_eq!(format!("{}", line1), >- "Line error: test message in line(13): test line"); >+ assert_eq!( >+ format!("{}", line1), >+ "Line error: test message in line(13): test line" >+ ); > assert_eq!(line1.description(), "test message"); > assert!(line1.cause().is_some()); > } > > #[test] > fn test_sdp_parser_error_unsupported() { > let unsupported1 = SdpParserError::Unsupported { > error: SdpParserInternalError::Generic("unsupported value".to_string()), > line: "unsupported line".to_string(), > line_number: 21, > }; >- assert_eq!(format!("{}", unsupported1), >- "Unsupported: unsupported value in line(21): unsupported line"); >+ assert_eq!( >+ format!("{}", unsupported1), >+ "Unsupported: unsupported value in line(21): unsupported line" >+ ); > assert_eq!(unsupported1.description(), "unsupported value"); > assert!(unsupported1.cause().is_some()); > } > > #[test] > fn test_sdp_parser_error_sequence() { > let sequence1 = SdpParserError::Sequence { > message: "sequence message".to_string(), > line_number: 42, > }; >- assert_eq!(format!("{}", sequence1), >- "Sequence error in line(42): sequence message"); >+ assert_eq!( >+ format!("{}", sequence1), >+ "Sequence error in line(42): sequence message" >+ ); > assert_eq!(sequence1.description(), "sequence message"); > assert!(sequence1.cause().is_none()); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs >index cd1f851aab29..4e6a5672166e 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/lib.rs >@@ -1,82 +1,86 @@ >-#![cfg_attr(feature="clippy", feature(plugin))] >+#![cfg_attr(feature = "clippy", feature(plugin))] > > #[macro_use] > extern crate log; >-#[cfg(feature="serialize")] >+#[cfg(feature = "serialize")] > #[macro_use] > extern crate serde_derive; >-#[cfg(feature="serialize")] >+#[cfg(feature = "serialize")] > extern crate serde; > >+use std::fmt; > use std::net::IpAddr; > use std::str::FromStr; >-use std::fmt; > > pub mod attribute_type; > pub mod error; > pub mod media_type; > pub mod network; > pub mod unsupported_types; > >-use attribute_type::{SdpAttribute, SdpSingleDirection, SdpAttributeType, parse_attribute, >- SdpAttributeSimulcastVersion, SdpAttributeRid}; >-use error::{SdpParserInternalError, SdpParserError}; >-use media_type::{SdpMedia, SdpMediaLine, parse_media, parse_media_vector, SdpProtocolValue, >- SdpMediaValue, SdpFormatList}; >+use attribute_type::{ >+ parse_attribute, SdpAttribute, SdpAttributeRid, SdpAttributeSimulcastVersion, SdpAttributeType, >+ SdpSingleDirection, >+}; >+use error::{SdpParserError, SdpParserInternalError}; >+use media_type::{ >+ parse_media, parse_media_vector, SdpFormatList, SdpMedia, SdpMediaLine, SdpMediaValue, >+ SdpProtocolValue, >+}; > use network::{parse_addrtype, parse_nettype, parse_unicast_addr}; >-use unsupported_types::{parse_email, parse_information, parse_key, parse_phone, parse_repeat, >- parse_uri, parse_zone}; >+use unsupported_types::{ >+ parse_email, parse_information, parse_key, parse_phone, parse_repeat, parse_uri, parse_zone, >+}; > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpBandwidth { > As(u32), > Ct(u32), > Tias(u32), > Unknown(String, u32), > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpConnection { > pub addr: IpAddr, > pub ttl: Option<u8>, > pub amount: Option<u32>, > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpOrigin { > pub username: String, > pub session_id: u64, > pub session_version: u64, > pub unicast_addr: IpAddr, > } > > impl fmt::Display for SdpOrigin { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- write!(f, >- "origin: {}, {}, {}, {}", >- self.username, >- self.session_id, >- self.session_version, >- self.unicast_addr) >+ write!( >+ f, >+ "origin: {}, {}, {}, {}", >+ self.username, self.session_id, self.session_version, self.unicast_addr >+ ) > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpTiming { > pub start: u64, > pub stop: u64, > } > >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpType { > Attribute(SdpAttribute), > Bandwidth(SdpBandwidth), > Connection(SdpConnection), > Email(String), > Information(String), > Key(String), > Media(SdpMediaLine), >@@ -85,41 +89,40 @@ pub enum SdpType { > Repeat(String), > Session(String), > Timing(SdpTiming), > Uri(String), > Version(u64), > Zone(String), > } > >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpLine { > pub line_number: usize, > pub sdp_type: SdpType, > } > >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpSession { > pub version: u64, > pub origin: SdpOrigin, > pub session: String, > pub connection: Option<SdpConnection>, > pub bandwidth: Vec<SdpBandwidth>, > pub timing: Option<SdpTiming>, > pub attribute: Vec<SdpAttribute>, > pub media: Vec<SdpMedia>, >- pub warnings: Vec<SdpParserError> >- // unsupported values: >- // information: Option<String>, >- // uri: Option<String>, >- // email: Option<String>, >- // phone: Option<String>, >- // repeat: Option<String>, >- // zone: Option<String>, >- // key: Option<String>, >+ pub warnings: Vec<SdpParserError>, // unsupported values: >+ // information: Option<String>, >+ // uri: Option<String>, >+ // email: Option<String>, >+ // phone: Option<String>, >+ // repeat: Option<String>, >+ // zone: Option<String>, >+ // key: Option<String> > } > > impl SdpSession { > pub fn new(version: u64, origin: SdpOrigin, session: String) -> SdpSession { > SdpSession { > version, > origin, > session, >@@ -157,71 +160,82 @@ impl SdpSession { > } > > pub fn set_timing(&mut self, t: &SdpTiming) { > self.timing = Some(t.clone()) > } > > pub fn add_attribute(&mut self, a: &SdpAttribute) -> Result<(), SdpParserInternalError> { > if !a.allowed_at_session_level() { >- return Err(SdpParserInternalError::Generic(format!("{} not allowed at session level", >- a))); >+ return Err(SdpParserInternalError::Generic(format!( >+ "{} not allowed at session level", >+ a >+ ))); > }; > Ok(self.attribute.push(a.clone())) > } > > pub fn extend_media(&mut self, v: Vec<SdpMedia>) { > self.media.extend(v) > } > > pub fn get_attribute(&self, t: SdpAttributeType) -> Option<&SdpAttribute> { >- self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).next() >+ self.attribute >+ .iter() >+ .filter(|a| SdpAttributeType::from(*a) == t) >+ .next() > } > >- pub fn add_media(&mut self, media_type: SdpMediaValue, direction: SdpAttribute, port: u32, >- protocol: SdpProtocolValue, addr: String) >- -> Result<(),SdpParserInternalError> { >- let mut media = SdpMedia::new(SdpMediaLine { >- media: media_type, >- port, >- port_count: 1, >- proto: protocol, >- formats: SdpFormatList::Integers(Vec::new()), >- }); >+ pub fn add_media( >+ &mut self, >+ media_type: SdpMediaValue, >+ direction: SdpAttribute, >+ port: u32, >+ protocol: SdpProtocolValue, >+ addr: String, >+ ) -> Result<(), SdpParserInternalError> { >+ let mut media = SdpMedia::new(SdpMediaLine { >+ media: media_type, >+ port, >+ port_count: 1, >+ proto: protocol, >+ formats: SdpFormatList::Integers(Vec::new()), >+ }); > >- media.add_attribute(&direction)?; >+ media.add_attribute(&direction)?; > >- media.set_connection(&SdpConnection { >- addr: IpAddr::from_str(addr.as_str())?, >- ttl: None, >- amount: None, >- })?; >+ media.set_connection(&SdpConnection { >+ addr: IpAddr::from_str(addr.as_str())?, >+ ttl: None, >+ amount: None, >+ })?; > >- self.media.push(media); >+ self.media.push(media); > >- Ok(()) >+ Ok(()) > } > } > > fn parse_session(value: &str) -> Result<SdpType, SdpParserInternalError> { > trace!("session: {}", value); > Ok(SdpType::Session(String::from(value))) > } > > #[test] > fn test_session_works() { > assert!(parse_session("topic").is_ok()); > } > >- > fn parse_version(value: &str) -> Result<SdpType, SdpParserInternalError> { > let ver = value.parse::<u64>()?; > if ver != 0 { >- return Err(SdpParserInternalError::Generic(format!("version type contains unsupported value {}", >- ver))); >+ return Err(SdpParserInternalError::Generic(format!( >+ "version type contains unsupported value {}", >+ ver >+ ))); > }; > trace!("version: {}", ver); > Ok(SdpType::Version(ver)) > } > > #[test] > fn test_version_works() { > assert!(parse_version("0").is_ok()); >@@ -233,61 +247,66 @@ fn test_version_unsupported_input() { > assert!(parse_version("11").is_err()); > assert!(parse_version("a").is_err()); > } > > fn parse_origin(value: &str) -> Result<SdpType, SdpParserInternalError> { > let mut tokens = value.split_whitespace(); > let username = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Origin type is missing username token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Origin type is missing username token".to_string(), >+ )) > } > Some(x) => x, > }; > let session_id = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Origin type is missing session ID token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Origin type is missing session ID token".to_string(), >+ )) > } > Some(x) => x.parse::<u64>()?, > }; > let session_version = match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Origin type is missing session version token" >- .to_string())) >+ "Origin type is missing session version token".to_string(), >+ )) > } > Some(x) => x.parse::<u64>()?, > }; > match tokens.next() { > None => { > return Err(SdpParserInternalError::Generic( >- "Origin type is missing session version token".to_string(), >- )) >+ "Origin type is missing session version token".to_string(), >+ )) > } > Some(x) => parse_nettype(x)?, > }; > let addrtype = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Origin type is missing address type token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Origin type is missing address type token".to_string(), >+ )) > } > Some(x) => parse_addrtype(x)?, > }; > let unicast_addr = match tokens.next() { > None => { >- return Err(SdpParserInternalError::Generic("Origin type is missing IP address token" >- .to_string())) >+ return Err(SdpParserInternalError::Generic( >+ "Origin type is missing IP address token".to_string(), >+ )) > } > Some(x) => parse_unicast_addr(x)?, > }; > if !addrtype.same_protocol(&unicast_addr) { >- return Err(SdpParserInternalError::Generic("Origin addrtype does not match address." >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "Origin addrtype does not match address.".to_string(), >+ )); > } > let o = SdpOrigin { > username: String::from(username), > session_id, > session_version, > unicast_addr, > }; > trace!("origin: {}", o); >@@ -325,36 +344,38 @@ fn test_origin_broken_ip_addr() { > #[test] > fn test_origin_addr_type_mismatch() { > assert!(parse_origin("mozilla 506705521068071134 0 IN IP4 ::1").is_err()); > } > > fn parse_connection(value: &str) -> Result<SdpType, SdpParserInternalError> { > let cv: Vec<&str> = value.split_whitespace().collect(); > if cv.len() != 3 { >- return Err(SdpParserInternalError::Generic("connection attribute must have three tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "connection attribute must have three tokens".to_string(), >+ )); > } > parse_nettype(cv[0])?; > let addrtype = parse_addrtype(cv[1])?; > let mut ttl = None; > let mut amount = None; > let mut addr_token = cv[2]; > if addr_token.find('/') != None { > let addr_tokens: Vec<&str> = addr_token.split('/').collect(); > if addr_tokens.len() >= 3 { > amount = Some(addr_tokens[2].parse::<u32>()?); > } > ttl = Some(addr_tokens[1].parse::<u8>()?); > addr_token = addr_tokens[0]; > } > let addr = parse_unicast_addr(addr_token)?; > if !addrtype.same_protocol(&addr) { >- return Err(SdpParserInternalError::Generic("connection addrtype does not match address." >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "connection addrtype does not match address.".to_string(), >+ )); > } > let c = SdpConnection { addr, ttl, amount }; > trace!("connection: {}", c.addr); > Ok(SdpType::Connection(c)) > } > > #[test] > fn connection_works() { >@@ -392,18 +413,19 @@ fn connection_broken_ip_addr() { > #[test] > fn connection_addr_type_mismatch() { > assert!(parse_connection("IN IP4 ::1").is_err()); > } > > fn parse_bandwidth(value: &str) -> Result<SdpType, SdpParserInternalError> { > let bv: Vec<&str> = value.split(':').collect(); > if bv.len() != 2 { >- return Err(SdpParserInternalError::Generic("bandwidth attribute must have two tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "bandwidth attribute must have two tokens".to_string(), >+ )); > } > let bandwidth = bv[1].parse::<u32>()?; > let bw = match bv[0].to_uppercase().as_ref() { > "AS" => SdpBandwidth::As(bandwidth), > "CT" => SdpBandwidth::Ct(bandwidth), > "TIAS" => SdpBandwidth::Tias(bandwidth), > _ => SdpBandwidth::Unknown(String::from(bv[0]), bandwidth), > }; >@@ -427,18 +449,19 @@ fn bandwidth_wrong_amount_of_tokens() { > #[test] > fn bandwidth_unsupported_type() { > assert!(parse_bandwidth("UNSUPPORTED:12345").is_ok()); > } > > fn parse_timing(value: &str) -> Result<SdpType, SdpParserInternalError> { > let tv: Vec<&str> = value.split_whitespace().collect(); > if tv.len() != 2 { >- return Err(SdpParserInternalError::Generic("timing attribute must have two tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "timing attribute must have two tokens".to_string(), >+ )); > } > let start = tv[0].parse::<u64>()?; > let stop = tv[1].parse::<u64>()?; > let t = SdpTiming { start, stop }; > trace!("timing: {}, {}", t.start, t.stop); > Ok(SdpType::Timing(t)) > } > >@@ -457,113 +480,106 @@ fn test_timing_non_numeric_tokens() { > fn test_timing_wrong_amount_of_tokens() { > assert!(parse_timing("0").is_err()); > assert!(parse_timing("0 0 0").is_err()); > } > > fn parse_sdp_line(line: &str, line_number: usize) -> Result<SdpLine, SdpParserError> { > if line.find('=') == None { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("missing = character in line" >- .to_string()), >- line: line.to_string(), >- line_number: line_number, >- }); >+ error: SdpParserInternalError::Generic("missing = character in line".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }); > } > let mut splitted_line = line.splitn(2, '='); > let line_type = match splitted_line.next() { > None => { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("missing type".to_string()), >- line: line.to_string(), >- line_number: line_number, >- }) >+ error: SdpParserInternalError::Generic("missing type".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }) > } > Some(t) => { > let trimmed = t.trim(); > if trimmed.len() > 1 { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("type too long".to_string()), >- line: line.to_string(), >- line_number: line_number, >- }); >+ error: SdpParserInternalError::Generic("type too long".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }); > } > if trimmed.is_empty() { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("type is empty".to_string()), >- line: line.to_string(), >- line_number: line_number, >- }); >+ error: SdpParserInternalError::Generic("type is empty".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }); > } > trimmed > } > }; > let line_value = match splitted_line.next() { > None => { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("missing value".to_string()), >- line: line.to_string(), >- line_number: line_number, >- }) >+ error: SdpParserInternalError::Generic("missing value".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }) > } > Some(v) => { > let trimmed = v.trim(); > if trimmed.is_empty() { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("value is empty".to_string()), >- line: line.to_string(), >- line_number: line_number, >- }); >+ error: SdpParserInternalError::Generic("value is empty".to_string()), >+ line: line.to_string(), >+ line_number: line_number, >+ }); > } > trimmed > } > }; > match line_type.to_lowercase().as_ref() { >- "a" => parse_attribute(line_value), >- "b" => parse_bandwidth(line_value), >- "c" => parse_connection(line_value), >- "e" => parse_email(line_value), >- "i" => parse_information(line_value), >- "k" => parse_key(line_value), >- "m" => parse_media(line_value), >- "o" => parse_origin(line_value), >- "p" => parse_phone(line_value), >- "r" => parse_repeat(line_value), >- "s" => parse_session(line_value), >- "t" => parse_timing(line_value), >- "u" => parse_uri(line_value), >- "v" => parse_version(line_value), >- "z" => parse_zone(line_value), >- _ => Err(SdpParserInternalError::Generic("unknown sdp type".to_string())), >- } >- .map(|sdp_type| { >- SdpLine { >- line_number, >- sdp_type, >- } >- }) >- .map_err(|e| match e { >- SdpParserInternalError::Generic(..) | >- SdpParserInternalError::Integer(..) | >- SdpParserInternalError::Float(..) | >- SdpParserInternalError::Address(..) => { >- SdpParserError::Line { >- error: e, >- line: line.to_string(), >- line_number: line_number, >- } >- } >- SdpParserInternalError::Unsupported(..) => { >- SdpParserError::Unsupported { >- error: e, >- line: line.to_string(), >- line_number: line_number, >- } >- } >- }) >+ "a" => parse_attribute(line_value), >+ "b" => parse_bandwidth(line_value), >+ "c" => parse_connection(line_value), >+ "e" => parse_email(line_value), >+ "i" => parse_information(line_value), >+ "k" => parse_key(line_value), >+ "m" => parse_media(line_value), >+ "o" => parse_origin(line_value), >+ "p" => parse_phone(line_value), >+ "r" => parse_repeat(line_value), >+ "s" => parse_session(line_value), >+ "t" => parse_timing(line_value), >+ "u" => parse_uri(line_value), >+ "v" => parse_version(line_value), >+ "z" => parse_zone(line_value), >+ _ => Err(SdpParserInternalError::Generic( >+ "unknown sdp type".to_string(), >+ )), >+ }.map(|sdp_type| SdpLine { >+ line_number, >+ sdp_type, >+ }).map_err(|e| match e { >+ SdpParserInternalError::Generic(..) >+ | SdpParserInternalError::Integer(..) >+ | SdpParserInternalError::Float(..) >+ | SdpParserInternalError::Address(..) => SdpParserError::Line { >+ error: e, >+ line: line.to_string(), >+ line_number: line_number, >+ }, >+ SdpParserInternalError::Unsupported(..) => SdpParserError::Unsupported { >+ error: e, >+ line: line.to_string(), >+ line_number: line_number, >+ }, >+ }) > } > > #[test] > fn test_parse_sdp_line_works() { > assert!(parse_sdp_line("v=0", 0).is_ok()); > assert!(parse_sdp_line("s=somesession", 0).is_ok()); > } > >@@ -613,122 +629,131 @@ fn test_parse_sdp_line_invalid_a_line() { > fn sanity_check_sdp_session(session: &SdpSession) -> Result<(), SdpParserError> { > let make_error = |x: &str| SdpParserError::Sequence { > message: x.to_string(), > line_number: 0, > }; > > if !session.timing.is_some() { > return Err(SdpParserError::Sequence { >- message: "Missing timing type".to_string(), >- line_number: 0, >- }); >+ message: "Missing timing type".to_string(), >+ line_number: 0, >+ }); > } > > if session.media.is_empty() { > return Err(SdpParserError::Sequence { >- message: "Missing media section".to_string(), >- line_number: 0, >- }); >+ message: "Missing media section".to_string(), >+ line_number: 0, >+ }); > } > > if session.get_connection().is_none() { > for msection in &session.media { > if msection.get_connection().is_none() { > return Err(SdpParserError::Sequence { > message: "Each media section must define a connection >- if it is not defined on session level".to_string(), >+ if it is not defined on session level" >+ .to_string(), > line_number: 0, > }); > } > } > } > > // Check that extmaps are not defined on session and media level > if session.get_attribute(SdpAttributeType::Extmap).is_some() { > for msection in &session.media { > if msection.get_attribute(SdpAttributeType::Extmap).is_some() { > return Err(SdpParserError::Sequence { >- message: "Extmap can't be define at session and media level" >- .to_string(), >- line_number: 0, >- }); >+ message: "Extmap can't be define at session and media level".to_string(), >+ line_number: 0, >+ }); > } > } > } > > for msection in &session.media { > if msection.get_attribute(SdpAttributeType::Sendonly).is_some() { >- if let Some(&SdpAttribute::Simulcast(ref x)) = msection.get_attribute(SdpAttributeType::Simulcast) { >+ if let Some(&SdpAttribute::Simulcast(ref x)) = >+ msection.get_attribute(SdpAttributeType::Simulcast) >+ { > if x.receive.len() > 0 { > return Err(SdpParserError::Sequence { >- message: "Simulcast can't define receive parameters for sendonly".to_string(), >+ message: "Simulcast can't define receive parameters for sendonly" >+ .to_string(), > line_number: 0, > }); > } > } > } > if msection.get_attribute(SdpAttributeType::Recvonly).is_some() { >- if let Some(&SdpAttribute::Simulcast(ref x)) = msection.get_attribute(SdpAttributeType::Simulcast) { >+ if let Some(&SdpAttribute::Simulcast(ref x)) = >+ msection.get_attribute(SdpAttributeType::Simulcast) >+ { > if x.send.len() > 0 { > return Err(SdpParserError::Sequence { > message: "Simulcast can't define send parameters for recvonly".to_string(), > line_number: 0, > }); > } > } > } > >- let rids:Vec<&SdpAttributeRid> = msection.get_attributes().iter().filter_map(|attr| { >- match attr { >- &SdpAttribute::Rid(ref rid) => Some(rid), >- _ => None, >- } >- }).collect(); >- let recv_rids:Vec<&str> = rids.iter().filter_map(|rid| { >- match rid.direction { >- SdpSingleDirection::Recv => Some(rid.id.as_str()), >- _ => None, >- } >- }).collect(); >- let send_rids:Vec<&str> = rids.iter().filter_map(|rid| { >- match rid.direction { >- SdpSingleDirection::Send => Some(rid.id.as_str()), >- _ => None, >- } >- }).collect(); >- >+ let rids: Vec<&SdpAttributeRid> = msection >+ .get_attributes() >+ .iter() >+ .filter_map(|attr| match attr { >+ &SdpAttribute::Rid(ref rid) => Some(rid), >+ _ => None, >+ }).collect(); >+ let recv_rids: Vec<&str> = rids >+ .iter() >+ .filter_map(|rid| match rid.direction { >+ SdpSingleDirection::Recv => Some(rid.id.as_str()), >+ _ => None, >+ }).collect(); >+ let send_rids: Vec<&str> = rids >+ .iter() >+ .filter_map(|rid| match rid.direction { >+ SdpSingleDirection::Send => Some(rid.id.as_str()), >+ _ => None, >+ }).collect(); > > for rid_format in rids.iter().flat_map(|rid| &rid.formats) { > match msection.get_formats() { > &SdpFormatList::Integers(ref int_fmt) => { >- if !int_fmt.contains(&(*rid_format as u32)) { >+ if !int_fmt.contains(&(*rid_format as u32)) { > return Err(make_error("Rid pts must be declared in the media section")); > } >- }, >+ } > &SdpFormatList::Strings(ref str_fmt) => { >- if !str_fmt.contains(&rid_format.to_string()) { >+ if !str_fmt.contains(&rid_format.to_string()) { > return Err(make_error("Rid pts must be declared in the media section")); > } > } > } > } > > if let Some(&SdpAttribute::Simulcast(ref simulcast)) = >- msection.get_attribute(SdpAttributeType::Simulcast) { >- let check_defined_rids = |simulcast_version_list: &Vec<SdpAttributeSimulcastVersion>, >- rid_ids: &[&str]| -> Result<(),SdpParserError> { >- for simulcast_rid in simulcast_version_list.iter().flat_map(|x| &x.ids) { >- if !rid_ids.contains(&simulcast_rid.id.as_str()) { >- return Err(make_error( >- "Simulcast RIDs must be defined in any rid attribute")); >+ msection.get_attribute(SdpAttributeType::Simulcast) >+ { >+ let check_defined_rids = >+ |simulcast_version_list: &Vec<SdpAttributeSimulcastVersion>, >+ rid_ids: &[&str]| >+ -> Result<(), SdpParserError> { >+ for simulcast_rid in simulcast_version_list.iter().flat_map(|x| &x.ids) { >+ if !rid_ids.contains(&simulcast_rid.id.as_str()) { >+ return Err(make_error( >+ "Simulcast RIDs must be defined in any rid attribute", >+ )); >+ } > } >- } >- Ok(()) >- }; >+ Ok(()) >+ }; > > check_defined_rids(&simulcast.receive, &recv_rids)?; > check_defined_rids(&simulcast.send, &send_rids)?; > } > } > > Ok(()) > } >@@ -785,41 +810,51 @@ fn test_sanity_check_sdp_session_media() { > > #[test] > fn test_sanity_check_sdp_session_extmap() { > let mut sdp_session = create_dummy_sdp_session(); > let t = SdpTiming { start: 0, stop: 0 }; > sdp_session.set_timing(&t); > sdp_session.extend_media(vec![create_dummy_media_section()]); > >- let attribute = parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time",); >+ let attribute = >+ parse_attribute("extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time"); > assert!(attribute.is_ok()); > let extmap; > if let SdpType::Attribute(a) = attribute.unwrap() { > extmap = a; > } else { > panic!("SdpType is not Attribute"); > } > let ret = sdp_session.add_attribute(&extmap); > assert!(ret.is_ok()); >- assert!(sdp_session.get_attribute(SdpAttributeType::Extmap).is_some()); >+ assert!( >+ sdp_session >+ .get_attribute(SdpAttributeType::Extmap) >+ .is_some() >+ ); > > assert!(sanity_check_sdp_session(&sdp_session).is_ok()); > >- let mattribute = parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level",); >+ let mattribute = >+ parse_attribute("extmap:1/sendonly urn:ietf:params:rtp-hdrext:ssrc-audio-level"); > assert!(mattribute.is_ok()); > let mextmap; > if let SdpType::Attribute(ma) = mattribute.unwrap() { > mextmap = ma; > } else { > panic!("SdpType is not Attribute"); > } > let mut second_media = create_dummy_media_section(); > assert!(second_media.add_attribute(&mextmap).is_ok()); >- assert!(second_media.get_attribute(SdpAttributeType::Extmap).is_some()); >+ assert!( >+ second_media >+ .get_attribute(SdpAttributeType::Extmap) >+ .is_some() >+ ); > > sdp_session.extend_media(vec![second_media]); > assert!(sdp_session.media.len() == 2); > > assert!(sanity_check_sdp_session(&sdp_session).is_err()); > > sdp_session.attribute = Vec::new(); > >@@ -835,106 +870,101 @@ fn test_sanity_check_sdp_session_simulcast() { > > assert!(sanity_check_sdp_session(&sdp_session).is_ok()); > } > > // TODO add unit tests > fn parse_sdp_vector(lines: &[SdpLine]) -> Result<SdpSession, SdpParserError> { > if lines.len() < 5 { > return Err(SdpParserError::Sequence { >- message: "SDP neeeds at least 5 lines".to_string(), >- line_number: 0, >- }); >+ message: "SDP neeeds at least 5 lines".to_string(), >+ line_number: 0, >+ }); > } > > // TODO are these mataches really the only way to verify the types? > let version: u64 = match lines[0].sdp_type { > SdpType::Version(v) => v, > _ => { > return Err(SdpParserError::Sequence { >- message: "first line needs to be version number".to_string(), >- line_number: lines[0].line_number, >- }) >+ message: "first line needs to be version number".to_string(), >+ line_number: lines[0].line_number, >+ }) > } > }; > let origin: SdpOrigin = match lines[1].sdp_type { > SdpType::Origin(ref v) => v.clone(), > _ => { > return Err(SdpParserError::Sequence { >- message: "second line needs to be origin".to_string(), >- line_number: lines[1].line_number, >- }) >+ message: "second line needs to be origin".to_string(), >+ line_number: lines[1].line_number, >+ }) > } > }; > let session: String = match lines[2].sdp_type { > SdpType::Session(ref v) => v.clone(), > _ => { > return Err(SdpParserError::Sequence { >- message: "third line needs to be session".to_string(), >- line_number: lines[2].line_number, >- }) >+ message: "third line needs to be session".to_string(), >+ line_number: lines[2].line_number, >+ }) > } > }; > let mut sdp_session = SdpSession::new(version, origin, session); > for (index, line) in lines.iter().enumerate().skip(3) { > match line.sdp_type { > SdpType::Attribute(ref a) => { > sdp_session > .add_attribute(a) >- .map_err(|e: SdpParserInternalError| { >- SdpParserError::Sequence { >- message: format!("{}", e), >- line_number: line.line_number, >- } >- })? >+ .map_err(|e: SdpParserInternalError| SdpParserError::Sequence { >+ message: format!("{}", e), >+ line_number: line.line_number, >+ })? > } > SdpType::Bandwidth(ref b) => sdp_session.add_bandwidth(b), > SdpType::Timing(ref t) => sdp_session.set_timing(t), > SdpType::Connection(ref c) => sdp_session.set_connection(c), > SdpType::Media(_) => sdp_session.extend_media(parse_media_vector(&lines[index..])?), >- SdpType::Origin(_) | >- SdpType::Session(_) | >- SdpType::Version(_) => { >+ SdpType::Origin(_) | SdpType::Session(_) | SdpType::Version(_) => { > return Err(SdpParserError::Sequence { >- message: "version, origin or session at wrong level".to_string(), >- line_number: line.line_number, >- }) >+ message: "version, origin or session at wrong level".to_string(), >+ line_number: line.line_number, >+ }) > } > // the line parsers throw unsupported errors for these already >- SdpType::Email(_) | >- SdpType::Information(_) | >- SdpType::Key(_) | >- SdpType::Phone(_) | >- SdpType::Repeat(_) | >- SdpType::Uri(_) | >- SdpType::Zone(_) => (), >+ SdpType::Email(_) >+ | SdpType::Information(_) >+ | SdpType::Key(_) >+ | SdpType::Phone(_) >+ | SdpType::Repeat(_) >+ | SdpType::Uri(_) >+ | SdpType::Zone(_) => (), > }; > if !sdp_session.media.is_empty() { > break; > }; > } > sanity_check_sdp_session(&sdp_session)?; > Ok(sdp_session) > } > > pub fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpParserError> { > if sdp.is_empty() { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("empty SDP".to_string()), >- line: sdp.to_string(), >- line_number: 0, >- }); >+ error: SdpParserInternalError::Generic("empty SDP".to_string()), >+ line: sdp.to_string(), >+ line_number: 0, >+ }); > } > if sdp.len() < 62 { > return Err(SdpParserError::Line { >- error: SdpParserInternalError::Generic("string to short to be valid SDP" >- .to_string()), >- line: sdp.to_string(), >- line_number: 0, >- }); >+ error: SdpParserInternalError::Generic("string to short to be valid SDP".to_string()), >+ line: sdp.to_string(), >+ line_number: 0, >+ }); > } > let lines = sdp.lines(); > let mut errors: Vec<SdpParserError> = Vec::new(); > let mut warnings: Vec<SdpParserError> = Vec::new(); > let mut sdp_lines: Vec<SdpLine> = Vec::new(); > for (line_number, line) in lines.enumerate() { > let stripped_line = line.trim(); > if stripped_line.is_empty() { >@@ -946,43 +976,39 @@ pub fn parse_sdp(sdp: &str, fail_on_warning: bool) -> Result<SdpSession, SdpPars > } > Err(e) => { > match e { > // FIXME is this really a good way to accomplish this? > SdpParserError::Line { > error, > line, > line_number, >- } => { >- errors.push(SdpParserError::Line { >- error, >- line, >- line_number, >- }) >- } >+ } => errors.push(SdpParserError::Line { >+ error, >+ line, >+ line_number, >+ }), > SdpParserError::Unsupported { > error, > line, > line_number, > } => { > warnings.push(SdpParserError::Unsupported { >- error, >- line, >- line_number, >- }); >+ error, >+ line, >+ line_number, >+ }); > } > SdpParserError::Sequence { > message, > line_number, >- } => { >- errors.push(SdpParserError::Sequence { >- message, >- line_number, >- }) >- } >+ } => errors.push(SdpParserError::Sequence { >+ message, >+ line_number, >+ }), > } > } > }; > } > > if fail_on_warning && (warnings.len() > 0) { > return Err(warnings[0].clone()); > } >@@ -1009,98 +1035,122 @@ fn test_parse_sdp_zero_length_string_fails() { > > #[test] > fn test_parse_sdp_to_short_string() { > assert!(parse_sdp("fooooobarrrr", true).is_err()); > } > > #[test] > fn test_parse_sdp_line_error() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 foobar\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_unsupported_error() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 0\r\n > m=foobar 0 UDP/TLS/RTP/SAVPF 0\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_unsupported_warning() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.0.0.0\r\n > s=-\r\n > c=IN IP4 198.51.100.7\r\n > t=0 0\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n > a=unsupported\r\n", >- false) >- .is_ok()); >+ false >+ ).is_ok() >+ ); > } > > #[test] > fn test_parse_sdp_sequence_error() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.0.0.0\r\n > t=0 0\r\n > s=-\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_integer_error() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 0\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n > a=rtcp:34er21\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_ipaddr_error() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.a.b.0\r\n > s=-\r\n > t=0 0\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_invalid_session_attribute() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.a.b.0\r\n > s=-\r\n > t=0 0\r\n > a=bundle-only\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } > > #[test] > fn test_parse_sdp_invalid_media_attribute() { >- assert!(parse_sdp("v=0\r\n >+ assert!( >+ parse_sdp( >+ "v=0\r\n > o=- 0 0 IN IP4 0.a.b.0\r\n > s=-\r\n > t=0 0\r\n > m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n > a=ice-lite\r\n", >- true) >- .is_err()); >+ true >+ ).is_err() >+ ); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs >index 457c035c5e01..b4b9252962a4 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/media_type.rs >@@ -1,25 +1,25 @@ >-use std::fmt; >-use {SdpType, SdpLine, SdpBandwidth, SdpConnection}; >-use attribute_type::{SdpAttribute, SdpAttributeType, SdpAttributeRtpmap, SdpAttributeSctpmap}; >+use attribute_type::{SdpAttribute, SdpAttributeRtpmap, SdpAttributeSctpmap, SdpAttributeType}; > use error::{SdpParserError, SdpParserInternalError}; >+use std::fmt; >+use {SdpBandwidth, SdpConnection, SdpLine, SdpType}; > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpMediaLine { > pub media: SdpMediaValue, > pub port: u32, > pub port_count: u32, > pub proto: SdpProtocolValue, > pub formats: SdpFormatList, > } > >-#[derive(Clone,Debug,PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[derive(Clone, Debug, PartialEq)] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpMediaValue { > Audio, > Video, > Application, > } > > impl fmt::Display for SdpMediaValue { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >@@ -27,18 +27,18 @@ impl fmt::Display for SdpMediaValue { > SdpMediaValue::Audio => "Audio", > SdpMediaValue::Video => "Video", > SdpMediaValue::Application => "Application", > }; > write!(f, "{}", printable) > } > } > >-#[derive(Clone,Debug,PartialEq)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[derive(Clone, Debug, PartialEq)] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpProtocolValue { > RtpSavpf, > UdpTlsRtpSavpf, > TcpTlsRtpSavpf, > DtlsSctp, > UdpDtlsSctp, > TcpDtlsSctp, > } >@@ -53,32 +53,32 @@ impl fmt::Display for SdpProtocolValue { > SdpProtocolValue::UdpDtlsSctp => "Udp/Dtls/Sctp", > SdpProtocolValue::TcpDtlsSctp => "Tcp/Dtls/Sctp", > }; > write!(f, "{}", printable) > } > } > > #[derive(Clone)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub enum SdpFormatList { > Integers(Vec<u32>), > Strings(Vec<String>), > } > > impl fmt::Display for SdpFormatList { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > match *self { > SdpFormatList::Integers(ref x) => write!(f, "{:?}", x), > SdpFormatList::Strings(ref x) => write!(f, "{:?}", x), > } > } > } > >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub struct SdpMedia { > media: SdpMediaLine, > connection: Option<SdpConnection>, > bandwidth: Vec<SdpBandwidth>, > attribute: Vec<SdpAttribute>, > // unsupported values: > // information: Option<String>, > // key: Option<String>, >@@ -127,85 +127,97 @@ impl SdpMedia { > } > > pub fn get_attributes(&self) -> &Vec<SdpAttribute> { > &self.attribute > } > > pub fn add_attribute(&mut self, attr: &SdpAttribute) -> Result<(), SdpParserInternalError> { > if !attr.allowed_at_media_level() { >- return Err(SdpParserInternalError::Generic(format!("{} not allowed at media level", >- attr))); >+ return Err(SdpParserInternalError::Generic(format!( >+ "{} not allowed at media level", >+ attr >+ ))); > } > Ok(self.attribute.push(attr.clone())) > } > > pub fn get_attribute(&self, t: SdpAttributeType) -> Option<&SdpAttribute> { >- self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).next() >+ self.attribute >+ .iter() >+ .filter(|a| SdpAttributeType::from(*a) == t) >+ .next() > } > > pub fn remove_attribute(&mut self, t: SdpAttributeType) { > self.attribute.retain(|a| SdpAttributeType::from(a) != t); > } > > pub fn set_attribute(&mut self, attr: &SdpAttribute) -> Result<(), SdpParserInternalError> { > self.remove_attribute(SdpAttributeType::from(attr)); > self.add_attribute(attr) > } > > pub fn remove_codecs(&mut self) { >- match self.media.formats{ >+ match self.media.formats { > SdpFormatList::Integers(_) => self.media.formats = SdpFormatList::Integers(Vec::new()), > SdpFormatList::Strings(_) => self.media.formats = SdpFormatList::Strings(Vec::new()), > } > >- self.attribute.retain({|x| >- match x { >- &SdpAttribute::Rtpmap(_) | >- &SdpAttribute::Fmtp(_) | >- &SdpAttribute::Rtcpfb(_) | >- &SdpAttribute::Sctpmap(_) => false, >- _ => true >+ self.attribute.retain({ >+ |x| match x { >+ &SdpAttribute::Rtpmap(_) >+ | &SdpAttribute::Fmtp(_) >+ | &SdpAttribute::Rtcpfb(_) >+ | &SdpAttribute::Sctpmap(_) => false, >+ _ => true, > } > }); > } > >- pub fn add_codec(&mut self, rtpmap: SdpAttributeRtpmap) -> Result<(),SdpParserInternalError> { >- match self.media.formats { >- SdpFormatList::Integers(ref mut x) => x.push(rtpmap.payload_type as u32), >- SdpFormatList::Strings(ref mut x) => x.push(rtpmap.payload_type.to_string()), >- } >+ pub fn add_codec(&mut self, rtpmap: SdpAttributeRtpmap) -> Result<(), SdpParserInternalError> { >+ match self.media.formats { >+ SdpFormatList::Integers(ref mut x) => x.push(rtpmap.payload_type as u32), >+ SdpFormatList::Strings(ref mut x) => x.push(rtpmap.payload_type.to_string()), >+ } > > self.add_attribute(&SdpAttribute::Rtpmap(rtpmap))?; > Ok(()) > } > > pub fn get_attributes_of_type(&self, t: SdpAttributeType) -> Vec<&SdpAttribute> { >- self.attribute.iter().filter(|a| SdpAttributeType::from(*a) == t).collect() >+ self.attribute >+ .iter() >+ .filter(|a| SdpAttributeType::from(*a) == t) >+ .collect() > } > > pub fn get_connection(&self) -> &Option<SdpConnection> { > &self.connection > } > > pub fn set_connection(&mut self, c: &SdpConnection) -> Result<(), SdpParserInternalError> { > if self.connection.is_some() { >- return Err(SdpParserInternalError::Generic("connection type already exists at this media level" >- .to_string(), >- )); >+ return Err(SdpParserInternalError::Generic( >+ "connection type already exists at this media level".to_string(), >+ )); > } > Ok(self.connection = Some(c.clone())) > } > >- pub fn add_datachannel(&mut self, name: String, port: u16, streams: u16, msg_size:u32) >- -> Result<(),SdpParserInternalError> { >- // Only one allowed, for now. This may change as the specs (and deployments) evolve. >+ pub fn add_datachannel( >+ &mut self, >+ name: String, >+ port: u16, >+ streams: u16, >+ msg_size: u32, >+ ) -> Result<(), SdpParserInternalError> { >+ // Only one allowed, for now. This may change as the specs (and deployments) evolve. > match self.media.proto { >- SdpProtocolValue::UdpDtlsSctp | >- SdpProtocolValue::TcpDtlsSctp => { >+ SdpProtocolValue::UdpDtlsSctp | SdpProtocolValue::TcpDtlsSctp => { > // new data channel format according to draft 21 > self.media.formats = SdpFormatList::Strings(vec![name]); > self.set_attribute(&SdpAttribute::SctpPort(port as u64))?; > } > _ => { > // old data channels format according to draft 05 > self.media.formats = SdpFormatList::Integers(vec![port as u32]); > self.set_attribute(&SdpAttribute::Sctpmap(SdpAttributeSctpmap { >@@ -219,38 +231,40 @@ impl SdpMedia { > self.set_attribute(&SdpAttribute::MaxMessageSize(msg_size as u64))?; > } > > Ok(()) > } > } > > #[cfg(test)] >-#[cfg_attr(feature="serialize", derive(Serialize))] >+#[cfg_attr(feature = "serialize", derive(Serialize))] > pub fn create_dummy_media_section() -> SdpMedia { > let media_line = SdpMediaLine { > media: SdpMediaValue::Audio, > port: 9, > port_count: 0, > proto: SdpProtocolValue::RtpSavpf, > formats: SdpFormatList::Integers(Vec::new()), > }; > SdpMedia::new(media_line) > } > > fn parse_media_token(value: &str) -> Result<SdpMediaValue, SdpParserInternalError> { > Ok(match value.to_lowercase().as_ref() { >- "audio" => SdpMediaValue::Audio, >- "video" => SdpMediaValue::Video, >- "application" => SdpMediaValue::Application, >- _ => { >- return Err(SdpParserInternalError::Unsupported(format!("unsupported media value: {}", >- value))) >- } >- }) >+ "audio" => SdpMediaValue::Audio, >+ "video" => SdpMediaValue::Video, >+ "application" => SdpMediaValue::Application, >+ _ => { >+ return Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported media value: {}", >+ value >+ ))) >+ } >+ }) > } > > #[test] > fn test_parse_media_token() { > let audio = parse_media_token("audio"); > assert!(audio.is_ok()); > assert_eq!(audio.unwrap(), SdpMediaValue::Audio); > let video = parse_media_token("VIDEO"); >@@ -259,30 +273,31 @@ fn test_parse_media_token() { > let app = parse_media_token("aPplIcatIOn"); > assert!(app.is_ok()); > assert_eq!(app.unwrap(), SdpMediaValue::Application); > > assert!(parse_media_token("").is_err()); > assert!(parse_media_token("foobar").is_err()); > } > >- > fn parse_protocol_token(value: &str) -> Result<SdpProtocolValue, SdpParserInternalError> { > Ok(match value.to_uppercase().as_ref() { >- "RTP/SAVPF" => SdpProtocolValue::RtpSavpf, >- "UDP/TLS/RTP/SAVPF" => SdpProtocolValue::UdpTlsRtpSavpf, >- "TCP/TLS/RTP/SAVPF" => SdpProtocolValue::TcpTlsRtpSavpf, >- "DTLS/SCTP" => SdpProtocolValue::DtlsSctp, >- "UDP/DTLS/SCTP" => SdpProtocolValue::UdpDtlsSctp, >- "TCP/DTLS/SCTP" => SdpProtocolValue::TcpDtlsSctp, >- _ => { >- return Err(SdpParserInternalError::Unsupported(format!("unsupported protocol value: {}", >- value))) >- } >- }) >+ "RTP/SAVPF" => SdpProtocolValue::RtpSavpf, >+ "UDP/TLS/RTP/SAVPF" => SdpProtocolValue::UdpTlsRtpSavpf, >+ "TCP/TLS/RTP/SAVPF" => SdpProtocolValue::TcpTlsRtpSavpf, >+ "DTLS/SCTP" => SdpProtocolValue::DtlsSctp, >+ "UDP/DTLS/SCTP" => SdpProtocolValue::UdpDtlsSctp, >+ "TCP/DTLS/SCTP" => SdpProtocolValue::TcpDtlsSctp, >+ _ => { >+ return Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported protocol value: {}", >+ value >+ ))) >+ } >+ }) > } > > #[test] > fn test_parse_protocol_token() { > let rtps = parse_protocol_token("rtp/savpf"); > assert!(rtps.is_ok()); > assert_eq!(rtps.unwrap(), SdpProtocolValue::RtpSavpf); > let udps = parse_protocol_token("udp/tls/rtp/savpf"); >@@ -303,27 +318,34 @@ fn test_parse_protocol_token() { > > assert!(parse_protocol_token("").is_err()); > assert!(parse_protocol_token("foobar").is_err()); > } > > pub fn parse_media(value: &str) -> Result<SdpType, SdpParserInternalError> { > let mv: Vec<&str> = value.split_whitespace().collect(); > if mv.len() < 4 { >- return Err(SdpParserInternalError::Generic("media attribute must have at least four tokens" >- .to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "media attribute must have at least four tokens".to_string(), >+ )); > } > let media = parse_media_token(mv[0])?; > let mut ptokens = mv[1].split('/'); > let port = match ptokens.next() { >- None => return Err(SdpParserInternalError::Generic("missing port token".to_string())), >+ None => { >+ return Err(SdpParserInternalError::Generic( >+ "missing port token".to_string(), >+ )) >+ } > Some(p) => p.parse::<u32>()?, > }; > if port > 65535 { >- return Err(SdpParserInternalError::Generic("media port token is too big".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "media port token is too big".to_string(), >+ )); > } > let port_count = match ptokens.next() { > None => 0, > Some(c) => c.parse::<u32>()?, > }; > let proto = parse_protocol_token(mv[2])?; > let fmt_slice: &[&str] = &mv[3..]; > let formats = match media { >@@ -407,102 +429,92 @@ fn test_media_invalid_payload() { > } > > pub fn parse_media_vector(lines: &[SdpLine]) -> Result<Vec<SdpMedia>, SdpParserError> { > let mut media_sections: Vec<SdpMedia> = Vec::new(); > let mut sdp_media = match lines[0].sdp_type { > SdpType::Media(ref v) => SdpMedia::new(v.clone()), > _ => { > return Err(SdpParserError::Sequence { >- message: "first line in media section needs to be a media line" >- .to_string(), >- line_number: lines[0].line_number, >- }) >+ message: "first line in media section needs to be a media line".to_string(), >+ line_number: lines[0].line_number, >+ }) > } > }; > > for line in lines.iter().skip(1) { > match line.sdp_type { > SdpType::Connection(ref c) => { > sdp_media > .set_connection(c) >- .map_err(|e: SdpParserInternalError| { >- SdpParserError::Sequence { >- message: format!("{}", e), >- line_number: line.line_number, >- } >- })? >+ .map_err(|e: SdpParserInternalError| SdpParserError::Sequence { >+ message: format!("{}", e), >+ line_number: line.line_number, >+ })? > } > SdpType::Bandwidth(ref b) => sdp_media.add_bandwidth(b), > SdpType::Attribute(ref a) => { > match a { > &SdpAttribute::DtlsMessage(_) => { > // Ignore this attribute on media level > Ok(()) >- }, >+ } > &SdpAttribute::Rtpmap(ref rtpmap) => { >- sdp_media.add_attribute(&SdpAttribute::Rtpmap( >- SdpAttributeRtpmap { >- payload_type: rtpmap.payload_type, >- codec_name: rtpmap.codec_name.clone(), >- frequency: rtpmap.frequency, >- channels: match sdp_media.media.media { >- SdpMediaValue::Video => Some(0), >- _ => rtpmap.channels >- }, >- } >- )) >- }, >- _ => { >- sdp_media.add_attribute(a) >+ sdp_media.add_attribute(&SdpAttribute::Rtpmap(SdpAttributeRtpmap { >+ payload_type: rtpmap.payload_type, >+ codec_name: rtpmap.codec_name.clone(), >+ frequency: rtpmap.frequency, >+ channels: match sdp_media.media.media { >+ SdpMediaValue::Video => Some(0), >+ _ => rtpmap.channels, >+ }, >+ })) > } >- }.map_err(|e: SdpParserInternalError| { >- SdpParserError::Sequence { >- message: format!("{}", e), >- line_number: line.line_number, >- } >- })? >+ _ => sdp_media.add_attribute(a), >+ }.map_err(|e: SdpParserInternalError| SdpParserError::Sequence { >+ message: format!("{}", e), >+ line_number: line.line_number, >+ })? > } > SdpType::Media(ref v) => { > media_sections.push(sdp_media); > sdp_media = SdpMedia::new(v.clone()); > } > >- SdpType::Email(_) | >- SdpType::Phone(_) | >- SdpType::Origin(_) | >- SdpType::Repeat(_) | >- SdpType::Session(_) | >- SdpType::Timing(_) | >- SdpType::Uri(_) | >- SdpType::Version(_) | >- SdpType::Zone(_) => { >+ SdpType::Email(_) >+ | SdpType::Phone(_) >+ | SdpType::Origin(_) >+ | SdpType::Repeat(_) >+ | SdpType::Session(_) >+ | SdpType::Timing(_) >+ | SdpType::Uri(_) >+ | SdpType::Version(_) >+ | SdpType::Zone(_) => { > return Err(SdpParserError::Sequence { >- message: "invalid type in media section".to_string(), >- line_number: line.line_number, >- }) >+ message: "invalid type in media section".to_string(), >+ line_number: line.line_number, >+ }) > } > > // the line parsers throw unsupported errors for these already >- SdpType::Information(_) | >- SdpType::Key(_) => (), >+ SdpType::Information(_) | SdpType::Key(_) => (), > }; > } > > media_sections.push(sdp_media); > > Ok(media_sections) > } > > #[test] > fn test_media_vector_first_line_failure() { > let mut sdp_lines: Vec<SdpLine> = Vec::new(); > let line = SdpLine { > line_number: 0, >- sdp_type: SdpType::Session("hello".to_string()) >+ sdp_type: SdpType::Session("hello".to_string()), > }; > sdp_lines.push(line); > assert!(parse_media_vector(&sdp_lines).is_err()); > } > > #[test] > fn test_media_vector_multiple_connections() { > let mut sdp_lines: Vec<SdpLine> = Vec::new(); >@@ -510,33 +522,34 @@ fn test_media_vector_multiple_connections() { > media: SdpMediaValue::Audio, > port: 9, > port_count: 0, > proto: SdpProtocolValue::RtpSavpf, > formats: SdpFormatList::Integers(Vec::new()), > }; > let media = SdpLine { > line_number: 0, >- sdp_type: SdpType::Media(media_line) >+ sdp_type: SdpType::Media(media_line), > }; > sdp_lines.push(media); >- use network::{parse_unicast_addr}; >+ use network::parse_unicast_addr; > let addr = parse_unicast_addr("127.0.0.1").unwrap(); > let c = SdpConnection { > addr, > ttl: None, >- amount: None }; >+ amount: None, >+ }; > let c1 = SdpLine { > line_number: 1, >- sdp_type: SdpType::Connection(c.clone()) >+ sdp_type: SdpType::Connection(c.clone()), > }; > sdp_lines.push(c1); > let c2 = SdpLine { > line_number: 2, >- sdp_type: SdpType::Connection(c) >+ sdp_type: SdpType::Connection(c), > }; > sdp_lines.push(c2); > assert!(parse_media_vector(&sdp_lines).is_err()); > } > > #[test] > fn test_media_vector_invalid_types() { > let mut sdp_lines: Vec<SdpLine> = Vec::new(); >@@ -544,24 +557,24 @@ fn test_media_vector_invalid_types() { > media: SdpMediaValue::Audio, > port: 9, > port_count: 0, > proto: SdpProtocolValue::RtpSavpf, > formats: SdpFormatList::Integers(Vec::new()), > }; > let media = SdpLine { > line_number: 0, >- sdp_type: SdpType::Media(media_line) >+ sdp_type: SdpType::Media(media_line), > }; > sdp_lines.push(media); >- use {SdpTiming}; >+ use SdpTiming; > let t = SdpTiming { start: 0, stop: 0 }; > let tline = SdpLine { > line_number: 1, >- sdp_type: SdpType::Timing(t) >+ sdp_type: SdpType::Timing(t), > }; > sdp_lines.push(tline); > assert!(parse_media_vector(&sdp_lines).is_err()); > } > > #[test] > fn test_media_vector_invalid_media_level_attribute() { > let mut sdp_lines: Vec<SdpLine> = Vec::new(); >@@ -569,19 +582,19 @@ fn test_media_vector_invalid_media_level_attribute() { > media: SdpMediaValue::Audio, > port: 9, > port_count: 0, > proto: SdpProtocolValue::RtpSavpf, > formats: SdpFormatList::Integers(Vec::new()), > }; > let media = SdpLine { > line_number: 0, >- sdp_type: SdpType::Media(media_line) >+ sdp_type: SdpType::Media(media_line), > }; > sdp_lines.push(media); > let a = SdpAttribute::IceLite; > let aline = SdpLine { > line_number: 1, >- sdp_type: SdpType::Attribute(a) >+ sdp_type: SdpType::Attribute(a), > }; > sdp_lines.push(aline); > assert!(parse_media_vector(&sdp_lines).is_err()); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/network.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/network.rs >index 2d768bfc995e..b3711d95b3f8 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/network.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/network.rs >@@ -1,62 +1,65 @@ >-use std::str::FromStr; > use std::fmt; > use std::net::IpAddr; >+use std::str::FromStr; > > use error::SdpParserInternalError; > >-#[derive(Clone,Copy,Debug,PartialEq)] >+#[derive(Clone, Copy, Debug, PartialEq)] > pub enum SdpAddrType { > IP4 = 4, > IP6 = 6, > } > > impl SdpAddrType { > pub fn same_protocol(&self, addr: &IpAddr) -> bool { >- (addr.is_ipv6() && *self == SdpAddrType::IP6) || >- (addr.is_ipv4() && *self == SdpAddrType::IP4) >+ (addr.is_ipv6() && *self == SdpAddrType::IP6) >+ || (addr.is_ipv4() && *self == SdpAddrType::IP4) > } > } > > impl fmt::Display for SdpAddrType { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > let printable = match *self { > SdpAddrType::IP4 => "Ip4", > SdpAddrType::IP6 => "Ip6", > }; > write!(f, "{}", printable) > } > } > > pub fn parse_nettype(value: &str) -> Result<(), SdpParserInternalError> { > if value.to_uppercase() != "IN" { >- return Err(SdpParserInternalError::Generic("nettype needs to be IN".to_string())); >+ return Err(SdpParserInternalError::Generic( >+ "nettype needs to be IN".to_string(), >+ )); > }; > Ok(()) > } > > #[test] > fn test_parse_nettype() { > let internet = parse_nettype("iN"); > assert!(internet.is_ok()); > > assert!(parse_nettype("").is_err()); > assert!(parse_nettype("FOO").is_err()); > } > > pub fn parse_addrtype(value: &str) -> Result<SdpAddrType, SdpParserInternalError> { > Ok(match value.to_uppercase().as_ref() { >- "IP4" => SdpAddrType::IP4, >- "IP6" => SdpAddrType::IP6, >- _ => { >- return Err(SdpParserInternalError::Generic("address type needs to be IP4 or IP6" >- .to_string())) >- } >- }) >+ "IP4" => SdpAddrType::IP4, >+ "IP6" => SdpAddrType::IP6, >+ _ => { >+ return Err(SdpParserInternalError::Generic( >+ "address type needs to be IP4 or IP6".to_string(), >+ )) >+ } >+ }) > } > > #[test] > fn test_parse_addrtype() { > let ip4 = parse_addrtype("iP4"); > assert!(ip4.is_ok()); > assert_eq!(ip4.unwrap(), SdpAddrType::IP4); > let ip6 = parse_addrtype("Ip6"); >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/src/unsupported_types.rs b/media/webrtc/signaling/src/sdp/rsdparsa/src/unsupported_types.rs >index 272224b6af0c..afce131c52c5 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/src/unsupported_types.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/src/unsupported_types.rs >@@ -1,74 +1,95 @@ > use error::SdpParserInternalError; > use SdpType; > > pub fn parse_repeat(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO implement this if it's ever needed >- Err(SdpParserInternalError::Unsupported(format!("unsupported type repeat: {} ", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type repeat: {} ", >+ value >+ ))) > } > > #[test] > fn test_repeat_works() { > // FIXME use a proper r value here > assert!(parse_repeat("0 0").is_err()); > } > > pub fn parse_zone(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO implement this if it's ever needed >- Err(SdpParserInternalError::Unsupported(format!("unsupported type zone: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type zone: {}", >+ value >+ ))) > } > > #[test] > fn test_zone_works() { > // FIXME use a proper z value here > assert!(parse_zone("0 0").is_err()); > } > > pub fn parse_key(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO implement this if it's ever needed >- Err(SdpParserInternalError::Unsupported(format!("unsupported type key: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type key: {}", >+ value >+ ))) > } > > #[test] > fn test_keys_works() { > // FIXME use a proper k value here > assert!(parse_key("12345").is_err()); > } > > pub fn parse_information(value: &str) -> Result<SdpType, SdpParserInternalError> { >- Err(SdpParserInternalError::Unsupported(format!("unsupported type information: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type information: {}", >+ value >+ ))) > } > > #[test] > fn test_information_works() { > assert!(parse_information("foobar").is_err()); > } > > pub fn parse_uri(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO check if this is really a URI >- Err(SdpParserInternalError::Unsupported(format!("unsupported type uri: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type uri: {}", >+ value >+ ))) > } > > #[test] > fn test_uri_works() { > assert!(parse_uri("http://www.mozilla.org").is_err()); > } > > pub fn parse_email(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO check if this is really an email address >- Err(SdpParserInternalError::Unsupported(format!("unsupported type email: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type email: {}", >+ value >+ ))) > } > > #[test] > fn test_email_works() { > assert!(parse_email("nils@mozilla.com").is_err()); > } > > pub fn parse_phone(value: &str) -> Result<SdpType, SdpParserInternalError> { > // TODO check if this is really a phone number >- Err(SdpParserInternalError::Unsupported(format!("unsupported type phone: {}", value))) >+ Err(SdpParserInternalError::Unsupported(format!( >+ "unsupported type phone: {}", >+ value >+ ))) > } > > #[test] > fn test_phone_works() { > assert!(parse_phone("+123456789").is_err()); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs b/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs >index 335949d0f678..f99ae6e3e985 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa/tests/unit_tests.rs >@@ -15,21 +15,25 @@ m=audio 0 UDP/TLS/RTP/SAVPF 0\r\n"; > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.session, "-"); > assert!(sdp.connection.is_some()); > assert_eq!(sdp.attribute.len(), 0); > assert_eq!(sdp.media.len(), 1); > > let msection = &(sdp.media[0]); >- assert_eq!(*msection.get_type(), >- rsdparsa::media_type::SdpMediaValue::Audio); >+ assert_eq!( >+ *msection.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Audio >+ ); > assert_eq!(msection.get_port(), 0); >- assert_eq!(*msection.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(msection.get_attributes().is_empty()); > assert!(msection.get_bandwidth().is_empty()); > assert!(msection.get_connection().is_none()); > } > > #[test] > fn parse_minimal_sdp_with_emtpy_lines() { > let sdp = "v=0\r\n >@@ -89,25 +93,33 @@ a=sendrecv\r\n"; > assert!(sdp_opt.is_some()); > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.session, "-"); > assert_eq!(sdp.attribute.len(), 0); > assert_eq!(sdp.media.len(), 1); > > let msection = &(sdp.media[0]); >- assert_eq!(*msection.get_type(), >- rsdparsa::media_type::SdpMediaValue::Video); >+ assert_eq!( >+ *msection.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Video >+ ); > assert_eq!(msection.get_port(), 0); >- assert_eq!(*msection.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(!msection.get_bandwidth().is_empty()); > assert!(!msection.get_connection().is_none()); > assert!(!msection.get_attributes().is_empty()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some()); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv) >+ .is_some() >+ ); > } > > #[test] > fn parse_firefox_audio_offer() { > let sdp = "v=0\r\n > o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 0\r\n >@@ -135,36 +147,88 @@ a=ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}\r\n"; > assert!(sdp_res.is_ok()); > let sdp_opt = sdp_res.ok(); > assert!(sdp_opt.is_some()); > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.media.len(), 1); > > let msection = &(sdp.media[0]); >- assert_eq!(*msection.get_type(), >- rsdparsa::media_type::SdpMediaValue::Audio); >+ assert_eq!( >+ *msection.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Audio >+ ); > assert_eq!(msection.get_port(), 9); >- assert_eq!(*msection.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(msection.get_connection().is_some()); > assert!(msection.get_bandwidth().is_empty()); > assert!(!msection.get_attributes().is_empty()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some()); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc) >+ .is_some() >+ ); > } > > #[test] > fn parse_firefox_video_offer() { > let sdp = "v=0\r\n > o=mozilla...THIS_IS_SDPARTA-52.0a1 506705521068071134 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 0\r\n >@@ -203,37 +267,93 @@ a=ssrc:2709871439 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}"; > assert!(sdp_res.is_ok()); > let sdp_opt = sdp_res.ok(); > assert!(sdp_opt.is_some()); > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.media.len(), 1); > > let msection = &(sdp.media[0]); >- assert_eq!(*msection.get_type(), >- rsdparsa::media_type::SdpMediaValue::Video); >+ assert_eq!( >+ *msection.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Video >+ ); > assert_eq!(msection.get_port(), 9); >- assert_eq!(*msection.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(msection.get_connection().is_some()); > assert!(msection.get_bandwidth().is_empty()); > assert!(!msection.get_attributes().is_empty()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Recvonly).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some()); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Recvonly) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Fmtp) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc) >+ .is_some() >+ ); > } > > #[test] > fn parse_firefox_datachannel_offer() { > let sdp = "v=0\r\n > o=mozilla...THIS_IS_SDPARTA-52.0a2 3327975756663609975 0 IN IP4 0.0.0.0\r\n > s=-\r\n > t=0 0\r\n >@@ -256,37 +376,93 @@ a=ssrc:3376683177 cname:{62f78ee0-620f-a043-86ca-b69f189f1aea}\r\n"; > assert!(sdp_res.is_ok()); > let sdp_opt = sdp_res.ok(); > assert!(sdp_opt.is_some()); > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.media.len(), 1); > > let msection = &(sdp.media[0]); >- assert_eq!(*msection.get_type(), >- rsdparsa::media_type::SdpMediaValue::Application); >+ assert_eq!( >+ *msection.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Application >+ ); > assert_eq!(msection.get_port(), 49760); >- assert_eq!(*msection.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::DtlsSctp); >+ assert_eq!( >+ *msection.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::DtlsSctp >+ ); > assert!(msection.get_connection().is_some()); > assert!(msection.get_bandwidth().is_empty()); > assert!(!msection.get_attributes().is_empty()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::EndOfCandidates).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux).is_some()); >- assert!(!msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sctpmap).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup).is_some()); >- assert!(msection.get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc).is_some()); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sendrecv) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Extmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IcePwd) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::IceUfrag) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::EndOfCandidates) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Mid) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Msid) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtcpfb) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::RtcpMux) >+ .is_some() >+ ); >+ assert!( >+ !msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Rtpmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Sctpmap) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Setup) >+ .is_some() >+ ); >+ assert!( >+ msection >+ .get_attribute(rsdparsa::attribute_type::SdpAttributeType::Ssrc) >+ .is_some() >+ ); > } > > #[test] > fn parse_chrome_audio_video_offer() { > let sdp = "v=0\r\n > o=- 3836772544440436510 2 IN IP4 127.0.0.1\r\n > s=-\r\n > t=0 0\r\n >@@ -377,31 +553,39 @@ a=ssrc:2673335628 label:b6ec5178-c611-403f-bbec-3833ed547c09\r\n"; > assert!(sdp_res.is_ok()); > let sdp_opt = sdp_res.ok(); > assert!(sdp_opt.is_some()); > let sdp = sdp_opt.unwrap(); > assert_eq!(sdp.version, 0); > assert_eq!(sdp.media.len(), 2); > > let msection1 = &(sdp.media[0]); >- assert_eq!(*msection1.get_type(), >- rsdparsa::media_type::SdpMediaValue::Audio); >+ assert_eq!( >+ *msection1.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Audio >+ ); > assert_eq!(msection1.get_port(), 9); >- assert_eq!(*msection1.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection1.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(!msection1.get_attributes().is_empty()); > assert!(msection1.get_connection().is_some()); > assert!(msection1.get_bandwidth().is_empty()); > > let msection2 = &(sdp.media[1]); >- assert_eq!(*msection2.get_type(), >- rsdparsa::media_type::SdpMediaValue::Video); >+ assert_eq!( >+ *msection2.get_type(), >+ rsdparsa::media_type::SdpMediaValue::Video >+ ); > assert_eq!(msection2.get_port(), 9); >- assert_eq!(*msection2.get_proto(), >- rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf); >+ assert_eq!( >+ *msection2.get_proto(), >+ rsdparsa::media_type::SdpProtocolValue::UdpTlsRtpSavpf >+ ); > assert!(!msection2.get_attributes().is_empty()); > assert!(msection2.get_connection().is_some()); > assert!(msection2.get_bandwidth().is_empty()); > } > > #[test] > fn parse_firefox_simulcast_offer() { > let sdp = "v=0\r\n >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs >index 936dfb6d179e..461f0ae1b094 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/attribute.rs >@@ -1,35 +1,36 @@ >-use std::slice; >-use libc::{size_t, uint8_t, uint16_t, uint32_t, int64_t, uint64_t, c_float}; >+use libc::{c_float, int64_t, size_t, uint16_t, uint32_t, uint64_t, uint8_t}; > use std::ptr; >+use std::slice; > >-use rsdparsa::SdpSession; >+use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; > use rsdparsa::attribute_type::*; >-use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG}; >+use rsdparsa::SdpSession; > >-use types::StringView; > use network::RustIpAddr; >- >+use types::StringView; > > #[no_mangle] > pub unsafe extern "C" fn num_attributes(session: *const SdpSession) -> u32 { > (*session).attribute.len() as u32 > } > > #[no_mangle] >-pub unsafe extern "C" fn get_attribute_ptr(session: *const SdpSession, >- index: u32, >- ret: *mut *const SdpAttribute) -> nsresult { >+pub unsafe extern "C" fn get_attribute_ptr( >+ session: *const SdpSession, >+ index: u32, >+ ret: *mut *const SdpAttribute, >+) -> nsresult { > match (*session).attribute.get(index as usize) { > Some(attribute) => { > *ret = attribute as *const SdpAttribute; > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > fn count_attribute(attributes: &[SdpAttribute], search: SdpAttributeType) -> usize { > let mut count = 0; > for attribute in (*attributes).iter() { > if SdpAttributeType::from(attribute) == search { > count += 1; >@@ -42,21 +43,27 @@ fn argsearch(attributes: &[SdpAttribute], attribute_type: SdpAttributeType) -> O > for (i, attribute) in (*attributes).iter().enumerate() { > if SdpAttributeType::from(attribute) == attribute_type { > return Some(i); > } > } > None > } > >-pub unsafe fn has_attribute(attributes: *const Vec<SdpAttribute>, attribute_type: SdpAttributeType) -> bool { >+pub unsafe fn has_attribute( >+ attributes: *const Vec<SdpAttribute>, >+ attribute_type: SdpAttributeType, >+) -> bool { > argsearch((*attributes).as_slice(), attribute_type).is_some() > } > >-fn get_attribute(attributes: &[SdpAttribute], attribute_type: SdpAttributeType) -> Option<&SdpAttribute> { >+fn get_attribute( >+ attributes: &[SdpAttribute], >+ attribute_type: SdpAttributeType, >+) -> Option<&SdpAttribute> { > argsearch(attributes, attribute_type).map(|i| &attributes[i]) > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub enum RustSdpAttributeDtlsMessageType { > Client, > Server, >@@ -64,97 +71,114 @@ pub enum RustSdpAttributeDtlsMessageType { > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeDtlsMessage { > pub role: uint8_t, > pub value: StringView, > } > >-impl<'a> From<&'a SdpAttributeDtlsMessage > for RustSdpAttributeDtlsMessage { >- fn from(other: &SdpAttributeDtlsMessage ) -> Self { >+impl<'a> From<&'a SdpAttributeDtlsMessage> for RustSdpAttributeDtlsMessage { >+ fn from(other: &SdpAttributeDtlsMessage) -> Self { > match other { > &SdpAttributeDtlsMessage::Client(ref x) => RustSdpAttributeDtlsMessage { > role: RustSdpAttributeDtlsMessageType::Client as uint8_t, > value: StringView::from(x.as_str()), > }, > &SdpAttributeDtlsMessage::Server(ref x) => RustSdpAttributeDtlsMessage { > role: RustSdpAttributeDtlsMessageType::Server as uint8_t, >- value: StringView::from(x.as_str()) >- } >+ value: StringView::from(x.as_str()), >+ }, > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_dtls_message(attributes: *const Vec<SdpAttribute>, >- ret: *mut RustSdpAttributeDtlsMessage) -> nsresult { >+pub unsafe extern "C" fn sdp_get_dtls_message( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut RustSdpAttributeDtlsMessage, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::DtlsMessage); > if let Some(&SdpAttribute::DtlsMessage(ref dtls_message)) = attr { > *ret = RustSdpAttributeDtlsMessage::from(dtls_message); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_iceufrag(attributes: *const Vec<SdpAttribute>, ret: *mut StringView) -> nsresult { >+pub unsafe extern "C" fn sdp_get_iceufrag( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut StringView, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceUfrag); > if let Some(&SdpAttribute::IceUfrag(ref string)) = attr { > *ret = StringView::from(string.as_str()); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_icepwd(attributes: *const Vec<SdpAttribute>, ret: *mut StringView) -> nsresult { >+pub unsafe extern "C" fn sdp_get_icepwd( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut StringView, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IcePwd); > if let Some(&SdpAttribute::IcePwd(ref string)) = attr { > *ret = StringView::from(string.as_str()); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_identity(attributes: *const Vec<SdpAttribute>, ret: *mut StringView) -> nsresult { >+pub unsafe extern "C" fn sdp_get_identity( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut StringView, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Identity); > if let Some(&SdpAttribute::Identity(ref string)) = attr { > *ret = StringView::from(string.as_str()); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_iceoptions(attributes: *const Vec<SdpAttribute>, ret: *mut *const Vec<String>) -> nsresult { >+pub unsafe extern "C" fn sdp_get_iceoptions( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut *const Vec<String>, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::IceOptions); > if let Some(&SdpAttribute::IceOptions(ref options)) = attr { > *ret = options; > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_maxptime(attributes: *const Vec<SdpAttribute>, ret: *mut uint64_t) -> nsresult { >+pub unsafe extern "C" fn sdp_get_maxptime( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut uint64_t, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::MaxPtime); > if let Some(&SdpAttribute::MaxPtime(ref max_ptime)) = attr { > *ret = *max_ptime; > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeFingerprint { > hash_algorithm: uint16_t, >- fingerprint: *const Vec<u8> >+ fingerprint: *const Vec<u8>, > } > > impl<'a> From<&'a SdpAttributeFingerprint> for RustSdpAttributeFingerprint { > fn from(other: &SdpAttributeFingerprint) -> Self { > RustSdpAttributeFingerprint { > hash_algorithm: other.hash_algorithm as uint16_t, > fingerprint: &other.fingerprint, > } >@@ -162,22 +186,30 @@ impl<'a> From<&'a SdpAttributeFingerprint> for RustSdpAttributeFingerprint { > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_fingerprint_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Fingerprint) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_fingerprints(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_fingerprints: *mut RustSdpAttributeFingerprint) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Fingerprint(ref data) = *x { >- Some(RustSdpAttributeFingerprint::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_fingerprints( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_fingerprints: *mut RustSdpAttributeFingerprint, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Fingerprint(ref data) = *x { >+ Some(RustSdpAttributeFingerprint::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let fingerprints = slice::from_raw_parts_mut(ret_fingerprints, ret_size); > fingerprints.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone)] > pub enum RustSdpAttributeSetup { > Active, >@@ -187,23 +219,26 @@ pub enum RustSdpAttributeSetup { > } > > impl<'a> From<&'a SdpAttributeSetup> for RustSdpAttributeSetup { > fn from(other: &SdpAttributeSetup) -> Self { > match *other { > SdpAttributeSetup::Active => RustSdpAttributeSetup::Active, > SdpAttributeSetup::Actpass => RustSdpAttributeSetup::Actpass, > SdpAttributeSetup::Holdconn => RustSdpAttributeSetup::Holdconn, >- SdpAttributeSetup::Passive => RustSdpAttributeSetup::Passive >+ SdpAttributeSetup::Passive => RustSdpAttributeSetup::Passive, > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_setup(attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeSetup) -> nsresult { >+pub unsafe extern "C" fn sdp_get_setup( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut RustSdpAttributeSetup, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Setup); > if let Some(&SdpAttribute::Setup(ref setup)) = attr { > *ret = RustSdpAttributeSetup::from(setup); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > >@@ -215,33 +250,41 @@ pub struct RustSdpAttributeSsrc { > pub value: StringView, > } > > impl<'a> From<&'a SdpAttributeSsrc> for RustSdpAttributeSsrc { > fn from(other: &SdpAttributeSsrc) -> Self { > RustSdpAttributeSsrc { > id: other.id, > attribute: StringView::from(&other.attribute), >- value: StringView::from(&other.value) >+ value: StringView::from(&other.value), > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_ssrc_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Ssrc) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_ssrcs(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_ssrcs: *mut RustSdpAttributeSsrc) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Ssrc(ref data) = *x { >- Some(RustSdpAttributeSsrc::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_ssrcs( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_ssrcs: *mut RustSdpAttributeSsrc, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Ssrc(ref data) = *x { >+ Some(RustSdpAttributeSsrc::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let ssrcs = slice::from_raw_parts_mut(ret_ssrcs, ret_size); > ssrcs.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeRtpmap { > pub payload_type: uint8_t, >@@ -251,41 +294,48 @@ pub struct RustSdpAttributeRtpmap { > } > > impl<'a> From<&'a SdpAttributeRtpmap> for RustSdpAttributeRtpmap { > fn from(other: &SdpAttributeRtpmap) -> Self { > RustSdpAttributeRtpmap { > payload_type: other.payload_type as uint8_t, > codec_name: StringView::from(other.codec_name.as_str()), > frequency: other.frequency as uint32_t, >- channels: other.channels.unwrap_or(1) >+ channels: other.channels.unwrap_or(1), > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_rtpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Rtpmap) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_rtpmaps(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rtpmaps: *mut RustSdpAttributeRtpmap) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Rtpmap(ref data) = *x { >- Some(RustSdpAttributeRtpmap::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_rtpmaps( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_rtpmaps: *mut RustSdpAttributeRtpmap, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Rtpmap(ref data) = *x { >+ Some(RustSdpAttributeRtpmap::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let rtpmaps = slice::from_raw_parts_mut(ret_rtpmaps, ret_size); > rtpmaps.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeFmtpParameters { >- > // H264 > pub packetization_mode: uint32_t, > pub level_asymmetry_allowed: bool, > pub profile_level_id: uint32_t, > pub max_fs: uint32_t, > pub max_cpb: uint32_t, > pub max_dpb: uint32_t, > pub max_br: uint32_t, >@@ -309,34 +359,34 @@ pub struct RustSdpAttributeFmtpParameters { > pub encodings: *const Vec<uint8_t>, > > // Unknown > pub unknown_tokens: *const Vec<String>, > } > > impl<'a> From<&'a SdpAttributeFmtpParameters> for RustSdpAttributeFmtpParameters { > fn from(other: &SdpAttributeFmtpParameters) -> Self { >- RustSdpAttributeFmtpParameters{ >- packetization_mode: other.packetization_mode, >- level_asymmetry_allowed: other.level_asymmetry_allowed, >- profile_level_id: other.profile_level_id, >- max_fs: other.max_fs, >- max_cpb: other.max_cpb, >- max_dpb: other.max_dpb, >- max_br: other.max_br, >- max_mbps: other.max_mbps, >- usedtx: other.usedtx, >- stereo: other.stereo, >- useinbandfec: other.useinbandfec, >- cbr: other.cbr, >- max_fr: other.max_fr, >- maxplaybackrate: other.maxplaybackrate, >- dtmf_tones: StringView::from(other.dtmf_tones.as_str()), >- encodings: &other.encodings, >- unknown_tokens: &other.unknown_tokens, >+ RustSdpAttributeFmtpParameters { >+ packetization_mode: other.packetization_mode, >+ level_asymmetry_allowed: other.level_asymmetry_allowed, >+ profile_level_id: other.profile_level_id, >+ max_fs: other.max_fs, >+ max_cpb: other.max_cpb, >+ max_dpb: other.max_dpb, >+ max_br: other.max_br, >+ max_mbps: other.max_mbps, >+ usedtx: other.usedtx, >+ stereo: other.stereo, >+ useinbandfec: other.useinbandfec, >+ cbr: other.cbr, >+ max_fr: other.max_fr, >+ maxplaybackrate: other.maxplaybackrate, >+ dtmf_tones: StringView::from(other.dtmf_tones.as_str()), >+ encodings: &other.encodings, >+ unknown_tokens: &other.unknown_tokens, > } > } > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeFmtp { > pub payload_type: uint8_t, >@@ -345,44 +395,52 @@ pub struct RustSdpAttributeFmtp { > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_fmtp_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Fmtp) > } > > fn find_payload_type(attributes: &[SdpAttribute], payload_type: u8) -> Option<&SdpAttributeRtpmap> { >- attributes.iter().filter_map(|x| if let SdpAttribute::Rtpmap(ref data) = *x { >- if data.payload_type == payload_type { >+ attributes >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Rtpmap(ref data) = *x { >+ if data.payload_type == payload_type { >+ Some(data) >+ } else { >+ None >+ } >+ } else { >+ None >+ } >+ }).next() >+} >+ >+#[no_mangle] >+pub unsafe extern "C" fn sdp_get_fmtp( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_fmtp: *mut RustSdpAttributeFmtp, >+) -> size_t { >+ let fmtps = (*attributes).iter().filter_map(|x| { >+ if let SdpAttribute::Fmtp(ref data) = *x { > Some(data) > } else { > None > } >- } else { >- None >- }).next() >-} >- >-#[no_mangle] >-pub unsafe extern "C" fn sdp_get_fmtp(attributes: *const Vec<SdpAttribute>, ret_size: size_t, >- ret_fmtp: *mut RustSdpAttributeFmtp) -> size_t { >- let fmtps = (*attributes).iter().filter_map(|x| if let SdpAttribute::Fmtp(ref data) = *x { >- Some(data) >- } else { >- None > }); > let mut rust_fmtps = Vec::new(); > for fmtp in fmtps { > if let Some(rtpmap) = find_payload_type((*attributes).as_slice(), fmtp.payload_type) { >- rust_fmtps.push( RustSdpAttributeFmtp{ >+ rust_fmtps.push(RustSdpAttributeFmtp { > payload_type: fmtp.payload_type as u8, > codec_name: StringView::from(rtpmap.codec_name.as_str()), > parameters: RustSdpAttributeFmtpParameters::from(&fmtp.parameters), >- } >- ); >+ }); > } > } > let fmtps = if ret_size <= rust_fmtps.len() { > slice::from_raw_parts_mut(ret_fmtp, ret_size) > } else { > slice::from_raw_parts_mut(ret_fmtp, rust_fmtps.len()) > }; > fmtps.copy_from_slice(rust_fmtps.as_slice()); >@@ -424,25 +482,26 @@ pub unsafe extern "C" fn sdp_get_sctp_port(attributes: *const Vec<SdpAttribute>) > pub struct RustSdpAttributeFlags { > pub ice_lite: bool, > pub rtcp_mux: bool, > pub rtcp_rsize: bool, > pub bundle_only: bool, > pub end_of_candidates: bool, > } > >- > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_attribute_flags(attributes: *const Vec<SdpAttribute>) -> RustSdpAttributeFlags { >+pub unsafe extern "C" fn sdp_get_attribute_flags( >+ attributes: *const Vec<SdpAttribute>, >+) -> RustSdpAttributeFlags { > let mut ret = RustSdpAttributeFlags { > ice_lite: false, > rtcp_mux: false, > rtcp_rsize: false, > bundle_only: false, >- end_of_candidates: false >+ end_of_candidates: false, > }; > for attribute in (*attributes).iter() { > if let SdpAttribute::IceLite = *attribute { > ret.ice_lite = true; > } else if let SdpAttribute::RtcpMux = *attribute { > ret.rtcp_mux = true; > } else if let SdpAttribute::RtcpRsize = *attribute { > ret.rtcp_rsize = true; >@@ -451,87 +510,108 @@ pub unsafe extern "C" fn sdp_get_attribute_flags(attributes: *const Vec<SdpAttri > } else if let SdpAttribute::EndOfCandidates = *attribute { > ret.end_of_candidates = true; > } > } > ret > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_mid(attributes: *const Vec<SdpAttribute>, ret: *mut StringView) -> nsresult { >- for attribute in (*attributes).iter(){ >+pub unsafe extern "C" fn sdp_get_mid( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut StringView, >+) -> nsresult { >+ for attribute in (*attributes).iter() { > if let SdpAttribute::Mid(ref data) = *attribute { > *ret = StringView::from(data.as_str()); > return NS_OK; > } > } > NS_ERROR_INVALID_ARG > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeMsid { > id: StringView, >- appdata: StringView >+ appdata: StringView, > } > > impl<'a> From<&'a SdpAttributeMsid> for RustSdpAttributeMsid { > fn from(other: &SdpAttributeMsid) -> Self { > RustSdpAttributeMsid { > id: StringView::from(other.id.as_str()), >- appdata: StringView::from(&other.appdata) >+ appdata: StringView::from(&other.appdata), > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_msid_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Msid) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_msids(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_msids: *mut RustSdpAttributeMsid) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Msid(ref data) = *x { >- Some(RustSdpAttributeMsid::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_msids( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_msids: *mut RustSdpAttributeMsid, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Msid(ref data) = *x { >+ Some(RustSdpAttributeMsid::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let msids = slice::from_raw_parts_mut(ret_msids, ret_size); > msids.copy_from_slice(attrs.as_slice()); > } > > // TODO: Finish msid attributes once parsing is changed upstream. > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeMsidSemantic { > pub semantic: StringView, >- pub msids: *const Vec<String> >+ pub msids: *const Vec<String>, > } > > impl<'a> From<&'a SdpAttributeMsidSemantic> for RustSdpAttributeMsidSemantic { > fn from(other: &SdpAttributeMsidSemantic) -> Self { > RustSdpAttributeMsidSemantic { > semantic: StringView::from(other.semantic.as_str()), >- msids: &other.msids >+ msids: &other.msids, > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_msid_semantic_count(attributes: *const Vec<SdpAttribute>) -> size_t { >+pub unsafe extern "C" fn sdp_get_msid_semantic_count( >+ attributes: *const Vec<SdpAttribute>, >+) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::MsidSemantic) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_msid_semantics(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_msid_semantics: *mut RustSdpAttributeMsidSemantic) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::MsidSemantic(ref data) = *x { >- Some(RustSdpAttributeMsidSemantic::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_msid_semantics( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_msid_semantics: *mut RustSdpAttributeMsidSemantic, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::MsidSemantic(ref data) = *x { >+ Some(RustSdpAttributeMsidSemantic::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let msid_semantics = slice::from_raw_parts_mut(ret_msid_semantics, ret_size); > msid_semantics.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub enum RustSdpAttributeGroupSemantic { > LipSynchronization, >@@ -541,148 +621,177 @@ pub enum RustSdpAttributeGroupSemantic { > ForwardErrorCorrection, > DecodingDependency, > Bundle, > } > > impl<'a> From<&'a SdpAttributeGroupSemantic> for RustSdpAttributeGroupSemantic { > fn from(other: &SdpAttributeGroupSemantic) -> Self { > match *other { >- SdpAttributeGroupSemantic::LipSynchronization => RustSdpAttributeGroupSemantic::LipSynchronization, >- SdpAttributeGroupSemantic::FlowIdentification => RustSdpAttributeGroupSemantic::FlowIdentification, >- SdpAttributeGroupSemantic::SingleReservationFlow => RustSdpAttributeGroupSemantic::SingleReservationFlow, >- SdpAttributeGroupSemantic::AlternateNetworkAddressType => RustSdpAttributeGroupSemantic::AlternateNetworkAddressType, >- SdpAttributeGroupSemantic::ForwardErrorCorrection => RustSdpAttributeGroupSemantic::ForwardErrorCorrection, >- SdpAttributeGroupSemantic::DecodingDependency => RustSdpAttributeGroupSemantic::DecodingDependency, >- SdpAttributeGroupSemantic::Bundle => RustSdpAttributeGroupSemantic::Bundle >+ SdpAttributeGroupSemantic::LipSynchronization => { >+ RustSdpAttributeGroupSemantic::LipSynchronization >+ } >+ SdpAttributeGroupSemantic::FlowIdentification => { >+ RustSdpAttributeGroupSemantic::FlowIdentification >+ } >+ SdpAttributeGroupSemantic::SingleReservationFlow => { >+ RustSdpAttributeGroupSemantic::SingleReservationFlow >+ } >+ SdpAttributeGroupSemantic::AlternateNetworkAddressType => { >+ RustSdpAttributeGroupSemantic::AlternateNetworkAddressType >+ } >+ SdpAttributeGroupSemantic::ForwardErrorCorrection => { >+ RustSdpAttributeGroupSemantic::ForwardErrorCorrection >+ } >+ SdpAttributeGroupSemantic::DecodingDependency => { >+ RustSdpAttributeGroupSemantic::DecodingDependency >+ } >+ SdpAttributeGroupSemantic::Bundle => RustSdpAttributeGroupSemantic::Bundle, > } > } > } > >- > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeGroup { > pub semantic: RustSdpAttributeGroupSemantic, >- pub tags: *const Vec<String> >+ pub tags: *const Vec<String>, > } > > impl<'a> From<&'a SdpAttributeGroup> for RustSdpAttributeGroup { > fn from(other: &SdpAttributeGroup) -> Self { > RustSdpAttributeGroup { > semantic: RustSdpAttributeGroupSemantic::from(&other.semantics), >- tags: &other.tags >+ tags: &other.tags, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_group_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Group) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_groups(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_groups: *mut RustSdpAttributeGroup) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Group(ref data) = *x { >- Some(RustSdpAttributeGroup::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_groups( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_groups: *mut RustSdpAttributeGroup, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Group(ref data) = *x { >+ Some(RustSdpAttributeGroup::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let groups = slice::from_raw_parts_mut(ret_groups, ret_size); > groups.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > pub struct RustSdpAttributeRtcp { > pub port: uint32_t, > pub unicast_addr: RustIpAddr, > } > > impl<'a> From<&'a SdpAttributeRtcp> for RustSdpAttributeRtcp { > fn from(other: &SdpAttributeRtcp) -> Self { > RustSdpAttributeRtcp { > port: other.port as u32, >- unicast_addr: RustIpAddr::from(&other.unicast_addr) >+ unicast_addr: RustIpAddr::from(&other.unicast_addr), > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_rtcp(attributes: *const Vec<SdpAttribute>, ret: *mut RustSdpAttributeRtcp) -> nsresult { >+pub unsafe extern "C" fn sdp_get_rtcp( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut RustSdpAttributeRtcp, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Rtcp); > if let Some(&SdpAttribute::Rtcp(ref data)) = attr { > *ret = RustSdpAttributeRtcp::from(data); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > >- > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeRtcpFb { > pub payload_type: u32, > pub feedback_type: u32, > pub parameter: StringView, >- pub extra: StringView >+ pub extra: StringView, > } > > impl<'a> From<&'a SdpAttributeRtcpFb> for RustSdpAttributeRtcpFb { > fn from(other: &SdpAttributeRtcpFb) -> Self { > RustSdpAttributeRtcpFb { >- payload_type: match other.payload_type{ >+ payload_type: match other.payload_type { > SdpAttributePayloadType::Wildcard => u32::max_value(), > SdpAttributePayloadType::PayloadType(x) => x as u32, > }, > feedback_type: other.feedback_type.clone() as u32, > parameter: StringView::from(other.parameter.as_str()), > extra: StringView::from(other.extra.as_str()), > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_rtcpfb_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Rtcpfb) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_rtcpfbs(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rtcpfbs: *mut RustSdpAttributeRtcpFb) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Rtcpfb(ref data) = *x { >- Some(RustSdpAttributeRtcpFb::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_rtcpfbs( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_rtcpfbs: *mut RustSdpAttributeRtcpFb, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Rtcpfb(ref data) = *x { >+ Some(RustSdpAttributeRtcpFb::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let rtcpfbs = slice::from_raw_parts_mut(ret_rtcpfbs, ret_size); > rtcpfbs.clone_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeImageAttrXYRange { > // range > pub min: uint32_t, > pub max: uint32_t, > pub step: uint32_t, > > // discrete values > pub discrete_values: *const Vec<u32>, > } > >-impl<'a> From<&'a SdpAttributeImageAttrXYRange > for RustSdpAttributeImageAttrXYRange { >+impl<'a> From<&'a SdpAttributeImageAttrXYRange> for RustSdpAttributeImageAttrXYRange { > fn from(other: &SdpAttributeImageAttrXYRange) -> Self { > match other { > &SdpAttributeImageAttrXYRange::Range(min, max, step) => { > RustSdpAttributeImageAttrXYRange { > min, > max, > step: step.unwrap_or(1), > discrete_values: ptr::null(), > } >- }, >+ } > &SdpAttributeImageAttrXYRange::DiscreteValues(ref discrete_values) => { > RustSdpAttributeImageAttrXYRange { > min: 0, > max: 1, > step: 1, > discrete_values, > } > } >@@ -699,46 +808,44 @@ pub struct RustSdpAttributeImageAttrSRange { > > // discrete values > pub discrete_values: *const Vec<c_float>, > } > > impl<'a> From<&'a SdpAttributeImageAttrSRange> for RustSdpAttributeImageAttrSRange { > fn from(other: &SdpAttributeImageAttrSRange) -> Self { > match other { >- &SdpAttributeImageAttrSRange::Range(min, max) => { >- RustSdpAttributeImageAttrSRange { >- min, >- max, >- discrete_values: ptr::null(), >- } >+ &SdpAttributeImageAttrSRange::Range(min, max) => RustSdpAttributeImageAttrSRange { >+ min, >+ max, >+ discrete_values: ptr::null(), > }, > &SdpAttributeImageAttrSRange::DiscreteValues(ref discrete_values) => { > RustSdpAttributeImageAttrSRange { > min: 0.0, > max: 1.0, > discrete_values, > } >- }, >+ } > } > } > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeImageAttrPRange { > pub min: c_float, > pub max: c_float, > } > >-impl<'a> From<&'a SdpAttributeImageAttrPRange > for RustSdpAttributeImageAttrPRange { >+impl<'a> From<&'a SdpAttributeImageAttrPRange> for RustSdpAttributeImageAttrPRange { > fn from(other: &SdpAttributeImageAttrPRange) -> Self { > RustSdpAttributeImageAttrPRange { > min: other.min, >- max: other.max >+ max: other.max, > } > } > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeImageAttrSet { > pub x: RustSdpAttributeImageAttrXYRange, >@@ -748,84 +855,85 @@ pub struct RustSdpAttributeImageAttrSet { > pub sar: RustSdpAttributeImageAttrSRange, > > pub has_par: bool, > pub par: RustSdpAttributeImageAttrPRange, > > pub q: c_float, > } > >-impl<'a> From<&'a SdpAttributeImageAttrSet > for RustSdpAttributeImageAttrSet { >+impl<'a> From<&'a SdpAttributeImageAttrSet> for RustSdpAttributeImageAttrSet { > fn from(other: &SdpAttributeImageAttrSet) -> Self { > RustSdpAttributeImageAttrSet { > x: RustSdpAttributeImageAttrXYRange::from(&other.x), > y: RustSdpAttributeImageAttrXYRange::from(&other.y), > > has_sar: other.sar.is_some(), > sar: match other.sar { > Some(ref x) => RustSdpAttributeImageAttrSRange::from(x), > // This is just any valid value accepted by rust, > // it might as well by uninitilized > None => RustSdpAttributeImageAttrSRange::from( >- &SdpAttributeImageAttrSRange::DiscreteValues(vec![])) >+ &SdpAttributeImageAttrSRange::DiscreteValues(vec![]), >+ ), > }, > > has_par: other.par.is_some(), > par: match other.par { > Some(ref x) => RustSdpAttributeImageAttrPRange::from(x), > // This is just any valid value accepted by rust, > // it might as well by uninitilized >- None => RustSdpAttributeImageAttrPRange { >- min: 0.0, >- max: 1.0, >- } >+ None => RustSdpAttributeImageAttrPRange { min: 0.0, max: 1.0 }, > }, > > q: other.q.unwrap_or(0.5), > } > } > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeImageAttrSetList { >- pub sets: *const Vec<SdpAttributeImageAttrSet> >+ pub sets: *const Vec<SdpAttributeImageAttrSet>, > } > >-impl<'a> From<&'a SdpAttributeImageAttrSetList > for RustSdpAttributeImageAttrSetList { >+impl<'a> From<&'a SdpAttributeImageAttrSetList> for RustSdpAttributeImageAttrSetList { > fn from(other: &SdpAttributeImageAttrSetList) -> Self { > match other { >- &SdpAttributeImageAttrSetList::Wildcard => >- RustSdpAttributeImageAttrSetList{ >- sets: ptr::null(), >- }, >- &SdpAttributeImageAttrSetList::Sets(ref sets) => >- RustSdpAttributeImageAttrSetList { >- sets: sets, >+ &SdpAttributeImageAttrSetList::Wildcard => { >+ RustSdpAttributeImageAttrSetList { sets: ptr::null() } >+ } >+ &SdpAttributeImageAttrSetList::Sets(ref sets) => { >+ RustSdpAttributeImageAttrSetList { sets: sets } > } > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_imageattr_get_set_count(sets: *const Vec<SdpAttributeImageAttrSet>) >- -> size_t { >+pub unsafe extern "C" fn sdp_imageattr_get_set_count( >+ sets: *const Vec<SdpAttributeImageAttrSet>, >+) -> size_t { > (*sets).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_imageattr_get_sets(sets: *const Vec<SdpAttributeImageAttrSet>, >- ret_size: size_t, >- ret: *mut RustSdpAttributeImageAttrSet) { >- let rust_sets: Vec<_> = (*sets).iter().map(RustSdpAttributeImageAttrSet::from).collect(); >+pub unsafe extern "C" fn sdp_imageattr_get_sets( >+ sets: *const Vec<SdpAttributeImageAttrSet>, >+ ret_size: size_t, >+ ret: *mut RustSdpAttributeImageAttrSet, >+) { >+ let rust_sets: Vec<_> = (*sets) >+ .iter() >+ .map(RustSdpAttributeImageAttrSet::from) >+ .collect(); > let sets = slice::from_raw_parts_mut(ret, ret_size); > sets.clone_from_slice(rust_sets.as_slice()); > } > >- > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeImageAttr { > pub pt: u32, > pub send: RustSdpAttributeImageAttrSetList, > pub recv: RustSdpAttributeImageAttrSetList, > } > >@@ -837,107 +945,125 @@ impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr { > SdpAttributePayloadType::PayloadType(x) => x as u32, > }, > send: RustSdpAttributeImageAttrSetList::from(&other.send), > recv: RustSdpAttributeImageAttrSetList::from(&other.recv), > } > } > } > >- > #[no_mangle] > pub unsafe extern "C" fn sdp_get_imageattr_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::ImageAttr) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_imageattrs(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_attrs: *mut RustSdpAttributeImageAttr) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::ImageAttr(ref data) = *x { >- Some(RustSdpAttributeImageAttr::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_imageattrs( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_attrs: *mut RustSdpAttributeImageAttr, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::ImageAttr(ref data) = *x { >+ Some(RustSdpAttributeImageAttr::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let imageattrs = slice::from_raw_parts_mut(ret_attrs, ret_size); > imageattrs.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeSctpmap { > pub port: uint32_t, > pub channels: uint32_t, > } > > impl<'a> From<&'a SdpAttributeSctpmap> for RustSdpAttributeSctpmap { > fn from(other: &SdpAttributeSctpmap) -> Self { > RustSdpAttributeSctpmap { > port: other.port as u32, >- channels: other.channels >+ channels: other.channels, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_sctpmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Sctpmap) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_sctpmaps(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_sctpmaps: *mut RustSdpAttributeSctpmap) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Sctpmap(ref data) = *x { >- Some(RustSdpAttributeSctpmap::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_sctpmaps( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_sctpmaps: *mut RustSdpAttributeSctpmap, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Sctpmap(ref data) = *x { >+ Some(RustSdpAttributeSctpmap::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let sctpmaps = slice::from_raw_parts_mut(ret_sctpmaps, ret_size); > sctpmaps.copy_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeSimulcastId { > pub id: StringView, > pub paused: bool, > } > > impl<'a> From<&'a SdpAttributeSimulcastId> for RustSdpAttributeSimulcastId { > fn from(other: &SdpAttributeSimulcastId) -> Self { >- RustSdpAttributeSimulcastId{ >+ RustSdpAttributeSimulcastId { > id: StringView::from(other.id.as_str()), >- paused: other.paused >+ paused: other.paused, > } > } > } > >- > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeSimulcastVersion { >- pub ids: *const Vec<SdpAttributeSimulcastId> >+ pub ids: *const Vec<SdpAttributeSimulcastId>, > } > > impl<'a> From<&'a SdpAttributeSimulcastVersion> for RustSdpAttributeSimulcastVersion { > fn from(other: &SdpAttributeSimulcastVersion) -> Self { >- RustSdpAttributeSimulcastVersion { >- ids: &other.ids, >- } >+ RustSdpAttributeSimulcastVersion { ids: &other.ids } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_simulcast_get_ids_count(ids: *const Vec<SdpAttributeSimulcastId>) >- -> size_t { >+pub unsafe extern "C" fn sdp_simulcast_get_ids_count( >+ ids: *const Vec<SdpAttributeSimulcastId>, >+) -> size_t { > (*ids).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_simulcast_get_ids(ids: *const Vec<SdpAttributeSimulcastId>, >- ret_size: size_t, >- ret: *mut RustSdpAttributeSimulcastId) { >- let rust_ids: Vec<_> = (*ids).iter().map(RustSdpAttributeSimulcastId::from).collect(); >+pub unsafe extern "C" fn sdp_simulcast_get_ids( >+ ids: *const Vec<SdpAttributeSimulcastId>, >+ ret_size: size_t, >+ ret: *mut RustSdpAttributeSimulcastId, >+) { >+ let rust_ids: Vec<_> = (*ids) >+ .iter() >+ .map(RustSdpAttributeSimulcastId::from) >+ .collect(); > let ids = slice::from_raw_parts_mut(ret, ret_size); > ids.clone_from_slice(rust_ids.as_slice()); > } > > #[repr(C)] > pub struct RustSdpAttributeSimulcast { > pub send: *const Vec<SdpAttributeSimulcastVersion>, > pub receive: *const Vec<SdpAttributeSimulcastVersion>, >@@ -949,172 +1075,185 @@ impl<'a> From<&'a SdpAttributeSimulcast> for RustSdpAttributeSimulcast { > send: &other.send, > receive: &other.receive, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_simulcast_get_version_count( >- version_list: *const Vec<SdpAttributeSimulcastVersion>) >- -> size_t { >+ version_list: *const Vec<SdpAttributeSimulcastVersion>, >+) -> size_t { > (*version_list).len() > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_simulcast_get_versions( >- version_list: *const Vec<SdpAttributeSimulcastVersion>, >- ret_size: size_t, ret: *mut RustSdpAttributeSimulcastVersion) { >- let rust_versions_list: Vec<_> = (*version_list).iter() >- .map(RustSdpAttributeSimulcastVersion::from) >- .collect(); >+ version_list: *const Vec<SdpAttributeSimulcastVersion>, >+ ret_size: size_t, >+ ret: *mut RustSdpAttributeSimulcastVersion, >+) { >+ let rust_versions_list: Vec<_> = (*version_list) >+ .iter() >+ .map(RustSdpAttributeSimulcastVersion::from) >+ .collect(); > let versions = slice::from_raw_parts_mut(ret, ret_size); > versions.clone_from_slice(rust_versions_list.as_slice()) > } > >- >- > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_simulcast(attributes: *const Vec<SdpAttribute>, >- ret: *mut RustSdpAttributeSimulcast) -> nsresult { >+pub unsafe extern "C" fn sdp_get_simulcast( >+ attributes: *const Vec<SdpAttribute>, >+ ret: *mut RustSdpAttributeSimulcast, >+) -> nsresult { > let attr = get_attribute((*attributes).as_slice(), SdpAttributeType::Simulcast); > if let Some(&SdpAttribute::Simulcast(ref data)) = attr { > *ret = RustSdpAttributeSimulcast::from(data); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub enum RustDirection { > Recvonly, > Sendonly, > Sendrecv, >- Inactive >+ Inactive, > } > > impl<'a> From<&'a Option<SdpAttributeDirection>> for RustDirection { > fn from(other: &Option<SdpAttributeDirection>) -> Self { > match *other { >- Some(ref direction) => { >- match *direction { >- SdpAttributeDirection::Recvonly => RustDirection::Recvonly, >- SdpAttributeDirection::Sendonly => RustDirection::Sendonly, >- SdpAttributeDirection::Sendrecv => RustDirection::Sendrecv >- } >+ Some(ref direction) => match *direction { >+ SdpAttributeDirection::Recvonly => RustDirection::Recvonly, >+ SdpAttributeDirection::Sendonly => RustDirection::Sendonly, >+ SdpAttributeDirection::Sendrecv => RustDirection::Sendrecv, > }, >- None => RustDirection::Inactive >+ None => RustDirection::Inactive, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_direction(attributes: *const Vec<SdpAttribute>) -> RustDirection { > for attribute in (*attributes).iter() { > match *attribute { > SdpAttribute::Recvonly => { > return RustDirection::Recvonly; >- }, >+ } > SdpAttribute::Sendonly => { > return RustDirection::Sendonly; >- }, >+ } > SdpAttribute::Sendrecv => { > return RustDirection::Sendrecv; >- }, >+ } > SdpAttribute::Inactive => { > return RustDirection::Inactive; >- }, >- _ => () >+ } >+ _ => (), > } > } > RustDirection::Sendrecv > } > > #[repr(C)] > pub struct RustSdpAttributeRemoteCandidate { > pub component: uint32_t, > pub address: RustIpAddr, > pub port: uint32_t, > } > >- > impl<'a> From<&'a SdpAttributeRemoteCandidate> for RustSdpAttributeRemoteCandidate { > fn from(other: &SdpAttributeRemoteCandidate) -> Self { > RustSdpAttributeRemoteCandidate { > component: other.component, > address: RustIpAddr::from(&other.address), >- port: other.port >+ port: other.port, > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_remote_candidate_count(attributes: *const Vec<SdpAttribute>) -> size_t { >+pub unsafe extern "C" fn sdp_get_remote_candidate_count( >+ attributes: *const Vec<SdpAttribute>, >+) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::RemoteCandidate) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_remote_candidates(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_candidates: *mut RustSdpAttributeRemoteCandidate) { >- let attrs = (*attributes).iter().filter_map(|x| if let SdpAttribute::RemoteCandidate(ref data) = *x { >- Some(RustSdpAttributeRemoteCandidate::from(data)) >- } else { >- None >+pub unsafe extern "C" fn sdp_get_remote_candidates( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_candidates: *mut RustSdpAttributeRemoteCandidate, >+) { >+ let attrs = (*attributes).iter().filter_map(|x| { >+ if let SdpAttribute::RemoteCandidate(ref data) = *x { >+ Some(RustSdpAttributeRemoteCandidate::from(data)) >+ } else { >+ None >+ } > }); > let candidates = slice::from_raw_parts_mut(ret_candidates, ret_size); > for (source, destination) in attrs.zip(candidates) { > *destination = source > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_candidate_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Candidate) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_candidates(attributes: *const Vec<SdpAttribute>, _ret_size: size_t, >- ret: *mut *const Vec<String>) { >- let attr_strings: Vec<String> = (*attributes).iter().filter_map( |x| { >- if let SdpAttribute::Candidate(ref attr) = *x { >- // The serialized attribute starts with "candidate:...", this needs to be removed >- Some(attr.to_string()[10..].to_string()) >- } else { >- None >- } >- }).collect(); >+pub unsafe extern "C" fn sdp_get_candidates( >+ attributes: *const Vec<SdpAttribute>, >+ _ret_size: size_t, >+ ret: *mut *const Vec<String>, >+) { >+ let attr_strings: Vec<String> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Candidate(ref attr) = *x { >+ // The serialized attribute starts with "candidate:...", this needs to be removed >+ Some(attr.to_string()[10..].to_string()) >+ } else { >+ None >+ } >+ }).collect(); > > *ret = Box::into_raw(Box::from(attr_strings)); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeRidParameters { > pub max_width: uint32_t, > pub max_height: uint32_t, > pub max_fps: uint32_t, > pub max_fs: uint32_t, > pub max_br: uint32_t, > pub max_pps: uint32_t, >- pub unknown:*const Vec<String> >+ pub unknown: *const Vec<String>, > } > > impl<'a> From<&'a SdpAttributeRidParameters> for RustSdpAttributeRidParameters { >- fn from(other: &SdpAttributeRidParameters) -> Self { >- RustSdpAttributeRidParameters { >- max_width: other.max_width, >- max_height: other.max_height, >- max_fps: other.max_fps, >- max_fs: other.max_fs, >- max_br: other.max_br, >- max_pps: other.max_pps, >+ fn from(other: &SdpAttributeRidParameters) -> Self { >+ RustSdpAttributeRidParameters { >+ max_width: other.max_width, >+ max_height: other.max_height, >+ max_fps: other.max_fps, >+ max_fs: other.max_fs, >+ max_br: other.max_br, >+ max_pps: other.max_pps, > >- unknown: &other.unknown >- } >- } >+ unknown: &other.unknown, >+ } >+ } > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeRid { > pub id: StringView, > pub direction: uint32_t, > pub formats: *const Vec<uint16_t>, >@@ -1135,55 +1274,71 @@ impl<'a> From<&'a SdpAttributeRid> for RustSdpAttributeRid { > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_rid_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Rid) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_rids(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rids: *mut RustSdpAttributeRid) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Rid(ref data) = *x { >- Some(RustSdpAttributeRid::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_rids( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_rids: *mut RustSdpAttributeRid, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Rid(ref data) = *x { >+ Some(RustSdpAttributeRid::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let rids = slice::from_raw_parts_mut(ret_rids, ret_size); > rids.clone_from_slice(attrs.as_slice()); > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct RustSdpAttributeExtmap { > pub id: uint16_t, > pub direction_specified: bool, > pub direction: RustDirection, > pub url: StringView, >- pub extension_attributes: StringView >+ pub extension_attributes: StringView, > } > > impl<'a> From<&'a SdpAttributeExtmap> for RustSdpAttributeExtmap { > fn from(other: &SdpAttributeExtmap) -> Self { > RustSdpAttributeExtmap { >- id : other.id as uint16_t, >+ id: other.id as uint16_t, > direction_specified: other.direction.is_some(), > direction: RustDirection::from(&other.direction), > url: StringView::from(other.url.as_str()), >- extension_attributes: StringView::from(&other.extension_attributes) >+ extension_attributes: StringView::from(&other.extension_attributes), > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_extmap_count(attributes: *const Vec<SdpAttribute>) -> size_t { > count_attribute((*attributes).as_slice(), SdpAttributeType::Extmap) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_extmaps(attributes: *const Vec<SdpAttribute>, ret_size: size_t, ret_rids: *mut RustSdpAttributeExtmap) { >- let attrs: Vec<_> = (*attributes).iter().filter_map(|x| if let SdpAttribute::Extmap(ref data) = *x { >- Some(RustSdpAttributeExtmap::from(data)) >- } else { >- None >- }).collect(); >+pub unsafe extern "C" fn sdp_get_extmaps( >+ attributes: *const Vec<SdpAttribute>, >+ ret_size: size_t, >+ ret_rids: *mut RustSdpAttributeExtmap, >+) { >+ let attrs: Vec<_> = (*attributes) >+ .iter() >+ .filter_map(|x| { >+ if let SdpAttribute::Extmap(ref data) = *x { >+ Some(RustSdpAttributeExtmap::from(data)) >+ } else { >+ None >+ } >+ }).collect(); > let extmaps = slice::from_raw_parts_mut(ret_rids, ret_size); > extmaps.copy_from_slice(attrs.as_slice()); > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs >index e9de855b6add..e736802c73c1 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/lib.rs >@@ -1,63 +1,65 @@ >-extern crate rsdparsa; > extern crate libc; >-#[macro_use] extern crate log; >+extern crate rsdparsa; >+#[macro_use] >+extern crate log; > extern crate nserror; > >-use std::ptr; >-use std::os::raw::c_char; > use std::error::Error; >+use std::os::raw::c_char; >+use std::ptr; > > use libc::size_t; > > use std::rc::Rc; > >-use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG}; >-use rsdparsa::{SdpTiming, SdpBandwidth, SdpSession}; >+use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; >+use rsdparsa::attribute_type::SdpAttribute; > use rsdparsa::error::SdpParserError; > use rsdparsa::media_type::{SdpMediaValue, SdpProtocolValue}; >-use rsdparsa::attribute_type::{SdpAttribute}; >+use rsdparsa::{SdpBandwidth, SdpSession, SdpTiming}; > >-pub mod types; >-pub mod network; > pub mod attribute; > pub mod media_section; >+pub mod network; >+pub mod types; > >+use network::{get_bandwidth, origin_view_helper, RustSdpConnection, RustSdpOrigin}; > pub use types::{StringView, NULL_STRING}; >-use network::{RustSdpOrigin, origin_view_helper, RustSdpConnection, >- get_bandwidth}; > > #[no_mangle] >-pub unsafe extern "C" fn parse_sdp(sdp: StringView, >- fail_on_warning: bool, >- session: *mut *const SdpSession, >- error: *mut *const SdpParserError) -> nsresult { >+pub unsafe extern "C" fn parse_sdp( >+ sdp: StringView, >+ fail_on_warning: bool, >+ session: *mut *const SdpSession, >+ error: *mut *const SdpParserError, >+) -> nsresult { > let sdp_str = match sdp.into() { > Ok(string) => string, > Err(boxed_error) => { > *session = ptr::null(); > *error = Box::into_raw(Box::new(SdpParserError::Sequence { > message: (*boxed_error).description().to_string(), > line_number: 0, > })); > return NS_ERROR_INVALID_ARG; > } > }; > > let parser_result = rsdparsa::parse_sdp(&sdp_str, fail_on_warning); > match parser_result { > Ok(parsed) => { >- *error = match parsed.warnings.len(){ >+ *error = match parsed.warnings.len() { > 0 => ptr::null(), > _ => Box::into_raw(Box::new(parsed.warnings[0].clone())), > }; > *session = Rc::into_raw(Rc::new(parsed)); > NS_OK >- }, >+ } > Err(e) => { > *session = ptr::null(); > debug!("{:?}", e); > debug!("Error parsing SDP in rust: {}", e.description()); > *error = Box::into_raw(Box::new(e)); > NS_ERROR_INVALID_ARG > } > } >@@ -75,167 +77,186 @@ pub unsafe extern "C" fn sdp_new_reference(session: *mut SdpSession) -> *const S > let ret = Rc::into_raw(Rc::clone(&original)); > Rc::into_raw(original); // So the original reference doesn't get dropped > ret > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_error_line_num(error: *mut SdpParserError) -> size_t { > match *error { >- SdpParserError::Line {line_number, ..} | >- SdpParserError::Unsupported { line_number, ..} | >- SdpParserError::Sequence {line_number, ..} => line_number >+ SdpParserError::Line { line_number, .. } >+ | SdpParserError::Unsupported { line_number, .. } >+ | SdpParserError::Sequence { line_number, .. } => line_number, > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_error_message(error: *mut SdpParserError) -> StringView { > StringView::from((*error).description()) > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_free_error(error: *mut SdpParserError) { > let e = Box::from_raw(error); > drop(e); > } > > #[no_mangle] >-pub unsafe extern "C" fn get_version(session: *const SdpSession) -> u64 { >+pub unsafe extern "C" fn get_version(session: *const SdpSession) -> u64 { > (*session).get_version() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_origin(session: *const SdpSession) -> RustSdpOrigin { >+pub unsafe extern "C" fn sdp_get_origin(session: *const SdpSession) -> RustSdpOrigin { > origin_view_helper((*session).get_origin()) > } > > #[no_mangle] > pub unsafe extern "C" fn session_view(session: *const SdpSession) -> StringView { > StringView::from((*session).get_session()) > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_session_has_connection(session: *const SdpSession) -> bool { > (*session).connection.is_some() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_session_connection(session: *const SdpSession, >- connection: *mut RustSdpConnection) -> nsresult { >+pub unsafe extern "C" fn sdp_get_session_connection( >+ session: *const SdpSession, >+ connection: *mut RustSdpConnection, >+) -> nsresult { > match (*session).connection { > Some(ref c) => { > *connection = RustSdpConnection::from(c); > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_add_media_section(session: *mut SdpSession, >- media_type: u32, direction: u32, >- port: u16, protocol: u32, >- addr_type: u32, addr: StringView) -> nsresult { >- >- let addr_str:String = match addr.into() { >- Ok(x) => x, >- Err(boxed_error) => { >- println!("Error while pasing string, description: {:?}", (*boxed_error).description()); >- return NS_ERROR_INVALID_ARG; >- } >+pub unsafe extern "C" fn sdp_add_media_section( >+ session: *mut SdpSession, >+ media_type: u32, >+ direction: u32, >+ port: u16, >+ protocol: u32, >+ addr_type: u32, >+ addr: StringView, >+) -> nsresult { >+ let addr_str: String = match addr.into() { >+ Ok(x) => x, >+ Err(boxed_error) => { >+ println!( >+ "Error while pasing string, description: {:?}", >+ (*boxed_error).description() >+ ); >+ return NS_ERROR_INVALID_ARG; >+ } > }; > > let media_type = match media_type { > 0 => SdpMediaValue::Audio, // MediaType::kAudio > 1 => SdpMediaValue::Video, // MediaType::kVideo > 3 => SdpMediaValue::Application, // MediaType::kApplication > _ => { >- return NS_ERROR_INVALID_ARG; >- } >+ return NS_ERROR_INVALID_ARG; >+ } > }; > let protocol = match protocol { >- 20 => SdpProtocolValue::RtpSavpf, // Protocol::kRtpSavpf >- 24 => SdpProtocolValue::UdpTlsRtpSavpf, // Protocol::kUdpTlsRtpSavpf >- 25 => SdpProtocolValue::TcpTlsRtpSavpf, // Protocol::kTcpTlsRtpSavpf >- 37 => SdpProtocolValue::DtlsSctp, // Protocol::kDtlsSctp >- 38 => SdpProtocolValue::UdpDtlsSctp, // Protocol::kUdpDtlsSctp >- 39 => SdpProtocolValue::TcpDtlsSctp, // Protocol::kTcpDtlsSctp >+ 20 => SdpProtocolValue::RtpSavpf, // Protocol::kRtpSavpf >+ 24 => SdpProtocolValue::UdpTlsRtpSavpf, // Protocol::kUdpTlsRtpSavpf >+ 25 => SdpProtocolValue::TcpTlsRtpSavpf, // Protocol::kTcpTlsRtpSavpf >+ 37 => SdpProtocolValue::DtlsSctp, // Protocol::kDtlsSctp >+ 38 => SdpProtocolValue::UdpDtlsSctp, // Protocol::kUdpDtlsSctp >+ 39 => SdpProtocolValue::TcpDtlsSctp, // Protocol::kTcpDtlsSctp > _ => { >- return NS_ERROR_INVALID_ARG; >- } >+ return NS_ERROR_INVALID_ARG; >+ } > }; > let direction = match direction { > 1 => SdpAttribute::Sendonly, > 2 => SdpAttribute::Recvonly, > 3 => SdpAttribute::Sendrecv, > _ => { >- return NS_ERROR_INVALID_ARG; >- } >+ return NS_ERROR_INVALID_ARG; >+ } > }; > > // Check that the provided address type is valid. The rust parser will find out > // on his own which address type was provided > match addr_type { >- // enum AddrType { kAddrTypeNone, kIPv4, kIPv6 }; >- // kAddrTypeNone is explicitly not covered as it is an 'invalid' flag >- 1...2 => (), >- _ => { >- return NS_ERROR_INVALID_ARG; >- } >+ // enum AddrType { kAddrTypeNone, kIPv4, kIPv6 }; >+ // kAddrTypeNone is explicitly not covered as it is an 'invalid' flag >+ 1...2 => (), >+ _ => { >+ return NS_ERROR_INVALID_ARG; >+ } > } > > match (*session).add_media(media_type, direction, port as u32, protocol, addr_str) { > Ok(_) => NS_OK, >- Err(_) => NS_ERROR_INVALID_ARG >+ Err(_) => NS_ERROR_INVALID_ARG, > } > } > > #[repr(C)] > #[derive(Clone)] > pub struct RustSdpTiming { > pub start: u64, > pub stop: u64, > } > > impl<'a> From<&'a SdpTiming> for RustSdpTiming { > fn from(timing: &SdpTiming) -> Self { >- RustSdpTiming {start: timing.start, stop: timing.stop} >+ RustSdpTiming { >+ start: timing.start, >+ stop: timing.stop, >+ } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_session_has_timing(session: *const SdpSession) -> bool { > (*session).timing.is_some() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_session_timing(session: *const SdpSession, >- timing: *mut RustSdpTiming) -> nsresult { >+pub unsafe extern "C" fn sdp_session_timing( >+ session: *const SdpSession, >+ timing: *mut RustSdpTiming, >+) -> nsresult { > match (*session).timing { > Some(ref t) => { > *timing = RustSdpTiming::from(t); > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_media_section_count(session: *const SdpSession) -> size_t { > (*session).media.len() > } > >- > #[no_mangle] >-pub unsafe extern "C" fn get_sdp_bandwidth(session: *const SdpSession, >- bandwidth_type: *const c_char) -> u32 { >+pub unsafe extern "C" fn get_sdp_bandwidth( >+ session: *const SdpSession, >+ bandwidth_type: *const c_char, >+) -> u32 { > get_bandwidth(&(*session).bandwidth, bandwidth_type) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_session_bandwidth_vec(session: *const SdpSession) -> *const Vec<SdpBandwidth> { >+pub unsafe extern "C" fn sdp_get_session_bandwidth_vec( >+ session: *const SdpSession, >+) -> *const Vec<SdpBandwidth> { > &(*session).bandwidth > } > > #[no_mangle] >-pub unsafe extern "C" fn get_sdp_session_attributes(session: *const SdpSession) -> *const Vec<SdpAttribute> { >+pub unsafe extern "C" fn get_sdp_session_attributes( >+ session: *const SdpSession, >+) -> *const Vec<SdpAttribute> { > &(*session).attribute > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs >index 6eed578712af..7f0d28488a24 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/media_section.rs >@@ -1,45 +1,46 @@ >-use std::ptr; > use std::os::raw::c_char; >+use std::ptr; > > use libc::{size_t, uint32_t}; > >-use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG}; >-use rsdparsa::{SdpBandwidth, SdpSession}; >-use rsdparsa::media_type::{SdpMedia, SdpMediaValue, SdpProtocolValue, >- SdpFormatList}; >+use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; > use rsdparsa::attribute_type::{SdpAttribute, SdpAttributeRtpmap}; >+use rsdparsa::media_type::{SdpFormatList, SdpMedia, SdpMediaValue, SdpProtocolValue}; >+use rsdparsa::{SdpBandwidth, SdpSession}; > > use network::{get_bandwidth, RustSdpConnection}; > use types::StringView; > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_section(session: *const SdpSession, >- index: size_t) -> *const SdpMedia { >+pub unsafe extern "C" fn sdp_get_media_section( >+ session: *const SdpSession, >+ index: size_t, >+) -> *const SdpMedia { > return match (*session).media.get(index) { > Some(m) => m, >- None => ptr::null() >+ None => ptr::null(), > }; > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub enum RustSdpMediaValue { > Audio, > Video, > Application, > } > > impl<'a> From<&'a SdpMediaValue> for RustSdpMediaValue { > fn from(val: &SdpMediaValue) -> Self { > match *val { > SdpMediaValue::Audio => RustSdpMediaValue::Audio, > SdpMediaValue::Video => RustSdpMediaValue::Video, >- SdpMediaValue::Application => RustSdpMediaValue::Application >+ SdpMediaValue::Application => RustSdpMediaValue::Application, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_rust_get_media_type(sdp_media: *const SdpMedia) -> RustSdpMediaValue { > RustSdpMediaValue::from((*sdp_media).get_type()) > } >@@ -64,37 +65,41 @@ impl<'a> From<&'a SdpProtocolValue> for RustSdpProtocolValue { > SdpProtocolValue::DtlsSctp => RustSdpProtocolValue::DtlsSctp, > SdpProtocolValue::UdpDtlsSctp => RustSdpProtocolValue::UdpDtlsSctp, > SdpProtocolValue::TcpDtlsSctp => RustSdpProtocolValue::TcpDtlsSctp, > } > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_protocol(sdp_media: *const SdpMedia) -> RustSdpProtocolValue { >+pub unsafe extern "C" fn sdp_get_media_protocol( >+ sdp_media: *const SdpMedia, >+) -> RustSdpProtocolValue { > RustSdpProtocolValue::from((*sdp_media).get_proto()) > } > > #[repr(C)] > #[derive(Clone, Copy)] > pub enum RustSdpFormatType { > Integers, >- Strings >+ Strings, > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_format_type(sdp_media: *const SdpMedia) -> RustSdpFormatType { >+pub unsafe extern "C" fn sdp_get_format_type(sdp_media: *const SdpMedia) -> RustSdpFormatType { > match *(*sdp_media).get_formats() { > SdpFormatList::Integers(_) => RustSdpFormatType::Integers, >- SdpFormatList::Strings(_) => RustSdpFormatType::Strings >+ SdpFormatList::Strings(_) => RustSdpFormatType::Strings, > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_format_string_vec(sdp_media: *const SdpMedia) -> *const Vec<String> { >+pub unsafe extern "C" fn sdp_get_format_string_vec( >+ sdp_media: *const SdpMedia, >+) -> *const Vec<String> { > if let SdpFormatList::Strings(ref formats) = *(*sdp_media).get_formats() { > formats > } else { > ptr::null() > } > } > > #[no_mangle] >@@ -117,80 +122,100 @@ pub unsafe extern "C" fn sdp_get_media_port(sdp_media: *const SdpMedia) -> uint3 > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_get_media_port_count(sdp_media: *const SdpMedia) -> uint32_t { > (*sdp_media).get_port_count() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_bandwidth(sdp_media: *const SdpMedia, >- bandwidth_type: *const c_char) -> uint32_t { >+pub unsafe extern "C" fn sdp_get_media_bandwidth( >+ sdp_media: *const SdpMedia, >+ bandwidth_type: *const c_char, >+) -> uint32_t { > get_bandwidth((*sdp_media).get_bandwidth(), bandwidth_type) > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_bandwidth_vec(sdp_media: *const SdpMedia) -> *const Vec<SdpBandwidth> { >+pub unsafe extern "C" fn sdp_get_media_bandwidth_vec( >+ sdp_media: *const SdpMedia, >+) -> *const Vec<SdpBandwidth> { > (*sdp_media).get_bandwidth() > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_media_has_connection(sdp_media: *const SdpMedia) -> bool { > (*sdp_media).get_connection().is_some() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_connection(sdp_media: *const SdpMedia, ret: *mut RustSdpConnection) -> nsresult { >+pub unsafe extern "C" fn sdp_get_media_connection( >+ sdp_media: *const SdpMedia, >+ ret: *mut RustSdpConnection, >+) -> nsresult { > if let &Some(ref connection) = (*sdp_media).get_connection() { > *ret = RustSdpConnection::from(connection); > return NS_OK; > } > NS_ERROR_INVALID_ARG > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_get_media_attribute_list(sdp_media: *const SdpMedia) -> *const Vec<SdpAttribute> { >+pub unsafe extern "C" fn sdp_get_media_attribute_list( >+ sdp_media: *const SdpMedia, >+) -> *const Vec<SdpAttribute> { > (*sdp_media).get_attributes() > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_media_clear_codecs(sdp_media: *mut SdpMedia) { > (*sdp_media).remove_codecs() > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_media_add_codec(sdp_media: *mut SdpMedia, pt: u8, >- codec_name: StringView, clockrate: u32, >- channels: u16) -> nsresult { >- let rtpmap = SdpAttributeRtpmap{ >- payload_type: pt, >- codec_name: match codec_name.into() { >- Ok(x) => x, >- Err(boxed_error) => { >- println!("Error while pasing string, description: {:?}", (*boxed_error).description()); >- return NS_ERROR_INVALID_ARG; >- } >- }, >- frequency: clockrate, >- channels: Some(channels as u32), >- }; >+pub unsafe extern "C" fn sdp_media_add_codec( >+ sdp_media: *mut SdpMedia, >+ pt: u8, >+ codec_name: StringView, >+ clockrate: u32, >+ channels: u16, >+) -> nsresult { >+ let rtpmap = SdpAttributeRtpmap { >+ payload_type: pt, >+ codec_name: match codec_name.into() { >+ Ok(x) => x, >+ Err(boxed_error) => { >+ println!( >+ "Error while pasing string, description: {:?}", >+ (*boxed_error).description() >+ ); >+ return NS_ERROR_INVALID_ARG; >+ } >+ }, >+ frequency: clockrate, >+ channels: Some(channels as u32), >+ }; > > match (*sdp_media).add_codec(rtpmap) { > Ok(_) => NS_OK, > Err(_) => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] >-pub unsafe extern "C" fn sdp_media_add_datachannel(sdp_media: *mut SdpMedia, name: StringView, >- port: u16, streams: u16, message_size: u32) >- -> nsresult { >+pub unsafe extern "C" fn sdp_media_add_datachannel( >+ sdp_media: *mut SdpMedia, >+ name: StringView, >+ port: u16, >+ streams: u16, >+ message_size: u32, >+) -> nsresult { > let name_str = match name.into() { > Ok(x) => x, > Err(_) => { > return NS_ERROR_INVALID_ARG; > } > }; >- match (*sdp_media).add_datachannel(name_str, port, streams, message_size){ >+ match (*sdp_media).add_datachannel(name_str, port, streams, message_size) { > Ok(_) => NS_OK, >- Err(_) => NS_ERROR_INVALID_ARG >+ Err(_) => NS_ERROR_INVALID_ARG, > } > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/network.rs b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/network.rs >index a1baf6dc940a..01ede83b98b0 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/network.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/network.rs >@@ -1,134 +1,136 @@ >+use std::ffi::{CStr, CString}; > use std::net::IpAddr; > use std::os::raw::c_char; >-use std::ffi::{CStr, CString}; > >-use libc::{uint8_t, uint64_t}; >+use libc::{uint64_t, uint8_t}; > >-use rsdparsa::{SdpOrigin, SdpConnection, SdpBandwidth}; >+use rsdparsa::{SdpBandwidth, SdpConnection, SdpOrigin}; > > use types::StringView; > > #[repr(C)] > #[derive(Clone, Copy, PartialEq)] > pub enum RustSdpAddrType { > None, > IP4, >- IP6 >+ IP6, > } > > impl<'a> From<&'a IpAddr> for RustSdpAddrType { > fn from(addr: &IpAddr) -> RustSdpAddrType { > match *addr { > IpAddr::V4(_) => RustSdpAddrType::IP4, >- IpAddr::V6(_) => RustSdpAddrType::IP6 >+ IpAddr::V6(_) => RustSdpAddrType::IP6, > } > } > } > > pub fn get_octets(addr: &IpAddr) -> [u8; 16] { > let mut octets = [0; 16]; > match *addr { > IpAddr::V4(v4_addr) => { > let v4_octets = v4_addr.octets(); > (&mut octets[0..4]).copy_from_slice(&v4_octets); >- }, >+ } > IpAddr::V6(v6_addr) => { > let v6_octets = v6_addr.octets(); > octets.copy_from_slice(&v6_octets); > } > } > octets > } > > #[repr(C)] > pub struct RustIpAddr { > addr_type: RustSdpAddrType, >- unicast_addr: [u8; 50] >+ unicast_addr: [u8; 50], > } > > impl<'a> From<&'a IpAddr> for RustIpAddr { > fn from(addr: &IpAddr) -> Self { > let mut c_addr = [0; 50]; > let str_addr = format!("{}", addr); > let str_bytes = str_addr.as_bytes(); > if str_bytes.len() < 50 { > c_addr[..str_bytes.len()].copy_from_slice(&str_bytes); > } >- RustIpAddr {addr_type: RustSdpAddrType::from(addr), >- unicast_addr: c_addr } >+ RustIpAddr { >+ addr_type: RustSdpAddrType::from(addr), >+ unicast_addr: c_addr, >+ } > } > } > > impl<'a> From<&'a Option<IpAddr>> for RustIpAddr { > fn from(addr: &Option<IpAddr>) -> Self { > match *addr { > Some(ref x) => RustIpAddr::from(x), > None => RustIpAddr { > addr_type: RustSdpAddrType::None, >- unicast_addr: [0; 50] >- } >+ unicast_addr: [0; 50], >+ }, > } > } > } > > #[repr(C)] > pub struct RustSdpConnection { > pub addr: RustIpAddr, > pub ttl: uint8_t, >- pub amount: uint64_t >+ pub amount: uint64_t, > } > > impl<'a> From<&'a SdpConnection> for RustSdpConnection { > fn from(sdp_connection: &SdpConnection) -> Self { > let ttl = match sdp_connection.ttl { > Some(x) => x as u8, >- None => 0 >+ None => 0, > }; > let amount = match sdp_connection.amount { > Some(x) => x as u64, >- None => 0 >+ None => 0, > }; >- RustSdpConnection { addr: RustIpAddr::from(&sdp_connection.addr), >- ttl: ttl, amount: amount } >+ RustSdpConnection { >+ addr: RustIpAddr::from(&sdp_connection.addr), >+ ttl: ttl, >+ amount: amount, >+ } > } > } > > #[repr(C)] > pub struct RustSdpOrigin { > username: StringView, > session_id: u64, > session_version: u64, > addr: RustIpAddr, > } > >- > fn bandwidth_match(str_bw: &str, enum_bw: &SdpBandwidth) -> bool { > match *enum_bw { > SdpBandwidth::As(_) => str_bw == "AS", > SdpBandwidth::Ct(_) => str_bw == "CT", > SdpBandwidth::Tias(_) => str_bw == "TIAS", > SdpBandwidth::Unknown(ref type_name, _) => str_bw == type_name, > } > } > > fn bandwidth_value(bandwidth: &SdpBandwidth) -> u32 { > match *bandwidth { >- SdpBandwidth::As(x) | SdpBandwidth::Ct(x) | >- SdpBandwidth::Tias(x) => x, >- SdpBandwidth::Unknown(_, _) => 0 >+ SdpBandwidth::As(x) | SdpBandwidth::Ct(x) | SdpBandwidth::Tias(x) => x, >+ SdpBandwidth::Unknown(_, _) => 0, > } > } > >-pub unsafe fn get_bandwidth(bandwidths: &Vec<SdpBandwidth>, >- bandwidth_type: *const c_char) -> u32 { >+pub unsafe fn get_bandwidth(bandwidths: &Vec<SdpBandwidth>, bandwidth_type: *const c_char) -> u32 { > let bw_type = match CStr::from_ptr(bandwidth_type).to_str() { > Ok(string) => string, >- Err(_) => return 0 >+ Err(_) => return 0, > }; > for bandwidth in bandwidths.iter() { > if bandwidth_match(bw_type, bandwidth) { > return bandwidth_value(bandwidth); > } > } > 0 > } >@@ -137,44 +139,44 @@ pub unsafe fn get_bandwidth(bandwidths: &Vec<SdpBandwidth>, > pub unsafe extern "C" fn sdp_serialize_bandwidth(bw: *const Vec<SdpBandwidth>) -> *mut c_char { > let mut builder = String::new(); > for bandwidth in (*bw).iter() { > match *bandwidth { > SdpBandwidth::As(val) => { > builder.push_str("b=AS:"); > builder.push_str(&val.to_string()); > builder.push_str("\r\n"); >- }, >+ } > SdpBandwidth::Ct(val) => { > builder.push_str("b=CT:"); > builder.push_str(&val.to_string()); > builder.push_str("\r\n"); >- }, >+ } > SdpBandwidth::Tias(val) => { > builder.push_str("b=TIAS:"); > builder.push_str(&val.to_string()); > builder.push_str("\r\n"); >- }, >+ } > SdpBandwidth::Unknown(ref name, val) => { > builder.push_str("b="); > builder.push_str(name.as_str()); > builder.push(':'); > builder.push_str(&val.to_string()); > builder.push_str("\r\n"); >- }, >+ } > } > } > CString::from_vec_unchecked(builder.into_bytes()).into_raw() > } > > #[no_mangle] > pub unsafe extern "C" fn sdp_free_string(s: *mut c_char) { > drop(CString::from_raw(s)); > } > > pub unsafe fn origin_view_helper(origin: &SdpOrigin) -> RustSdpOrigin { > RustSdpOrigin { > username: StringView::from(origin.username.as_str()), > session_id: origin.session_id, > session_version: origin.session_version, >- addr: RustIpAddr::from(&origin.unicast_addr) >+ addr: RustIpAddr::from(&origin.unicast_addr), > } > } >diff --git a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs >index 8e4674c26cbf..ce90e0e05ddf 100644 >--- a/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs >+++ b/media/webrtc/signaling/src/sdp/rsdparsa_capi/src/types.rs >@@ -1,155 +1,175 @@ >-use libc::{size_t, uint8_t, uint16_t, uint32_t}; >-use std::ffi::CStr; >-use std::{str, slice}; >-use std::error::Error; >+use libc::{size_t, uint16_t, uint32_t, uint8_t}; > use std::boxed::Box; >+use std::error::Error; >+use std::ffi::CStr; >+use std::{slice, str}; > >-use nserror::{nsresult, NS_OK, NS_ERROR_INVALID_ARG}; >+use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_OK}; > > #[repr(C)] > #[derive(Clone, Copy)] > pub struct StringView { > buffer: *const u8, >- len: size_t >+ len: size_t, > } > >-pub const NULL_STRING: StringView = StringView { buffer: 0 as *const u8, >- len: 0 }; >+pub const NULL_STRING: StringView = StringView { >+ buffer: 0 as *const u8, >+ len: 0, >+}; > > impl<'a> From<&'a str> for StringView { > fn from(input: &str) -> StringView { >- StringView { buffer: input.as_ptr(), len: input.len()} >+ StringView { >+ buffer: input.as_ptr(), >+ len: input.len(), >+ } > } > } > >-impl Into<Result<String,Box<Error>>> for StringView { >- fn into(self) -> Result<String,Box<Error>> { >- >+impl Into<Result<String, Box<Error>>> for StringView { >+ fn into(self) -> Result<String, Box<Error>> { > // This block must be unsafe as it converts a StringView, most likly provided from the > // C++ code, into a rust String and thus needs to operate with raw pointers. > let string_slice: &[u8]; > unsafe { > // Add one to the length as the length passed in the StringView is the length of > // the string and is missing the null terminator >- string_slice = slice::from_raw_parts(self.buffer, self.len+1 as usize); >+ string_slice = slice::from_raw_parts(self.buffer, self.len + 1 as usize); > } > >- let c_str = match CStr::from_bytes_with_nul(string_slice) { >- Ok(string) => string, >- Err(x) => { return Err(Box::new(x)); }, >- }; >+ let c_str = match CStr::from_bytes_with_nul(string_slice) { >+ Ok(string) => string, >+ Err(x) => { >+ return Err(Box::new(x)); >+ } >+ }; > >- let str_slice: &str = match str::from_utf8(c_str.to_bytes()) { >- Ok(string) => string, >- Err(x) => { return Err(Box::new(x)); }, >- }; >+ let str_slice: &str = match str::from_utf8(c_str.to_bytes()) { >+ Ok(string) => string, >+ Err(x) => { >+ return Err(Box::new(x)); >+ } >+ }; > >- Ok(str_slice.to_string()) >+ Ok(str_slice.to_string()) > } > } > > impl<'a, T: AsRef<str>> From<&'a Option<T>> for StringView { > fn from(input: &Option<T>) -> StringView { > match *input { >- Some(ref x) => StringView { buffer: x.as_ref().as_ptr(), >- len: x.as_ref().len()}, >- None => NULL_STRING >+ Some(ref x) => StringView { >+ buffer: x.as_ref().as_ptr(), >+ len: x.as_ref().len(), >+ }, >+ None => NULL_STRING, > } > } > } > > #[no_mangle] > pub unsafe extern "C" fn string_vec_len(vec: *const Vec<String>) -> size_t { > (*vec).len() as size_t > } > > #[no_mangle] >-pub unsafe extern "C" fn string_vec_get_view(vec: *const Vec<String>, >- index: size_t, >- ret: *mut StringView) -> nsresult { >+pub unsafe extern "C" fn string_vec_get_view( >+ vec: *const Vec<String>, >+ index: size_t, >+ ret: *mut StringView, >+) -> nsresult { > match (*vec).get(index) { > Some(ref string) => { > *ret = StringView::from(string.as_str()); > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] > pub unsafe extern "C" fn free_boxed_string_vec(ptr: *mut Vec<String>) -> nsresult { > drop(Box::from_raw(ptr)); > NS_OK > } > > #[no_mangle] > pub unsafe extern "C" fn f32_vec_len(vec: *const Vec<f32>) -> size_t { > (*vec).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn f32_vec_get(vec: *const Vec<f32>, >- index: size_t, >- ret: *mut f32) -> nsresult { >+pub unsafe extern "C" fn f32_vec_get( >+ vec: *const Vec<f32>, >+ index: size_t, >+ ret: *mut f32, >+) -> nsresult { > match (*vec).get(index) { > Some(val) => { > *ret = *val; > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] > pub unsafe extern "C" fn u32_vec_len(vec: *const Vec<u32>) -> size_t { > (*vec).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn u32_vec_get(vec: *const Vec<u32>, >- index: size_t, >- ret: *mut uint32_t) -> nsresult { >+pub unsafe extern "C" fn u32_vec_get( >+ vec: *const Vec<u32>, >+ index: size_t, >+ ret: *mut uint32_t, >+) -> nsresult { > match (*vec).get(index) { > Some(val) => { > *ret = *val; > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] > pub unsafe extern "C" fn u16_vec_len(vec: *const Vec<u16>) -> size_t { > (*vec).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn u16_vec_get(vec: *const Vec<u16>, >- index: size_t, >- ret: *mut uint16_t) -> nsresult { >+pub unsafe extern "C" fn u16_vec_get( >+ vec: *const Vec<u16>, >+ index: size_t, >+ ret: *mut uint16_t, >+) -> nsresult { > match (*vec).get(index) { > Some(val) => { > *ret = *val; > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } > > #[no_mangle] > pub unsafe extern "C" fn u8_vec_len(vec: *const Vec<u8>) -> size_t { > (*vec).len() > } > > #[no_mangle] >-pub unsafe extern "C" fn u8_vec_get(vec: *const Vec<u8>, >- index: size_t, >- ret: *mut uint8_t) -> nsresult { >+pub unsafe extern "C" fn u8_vec_get( >+ vec: *const Vec<u8>, >+ index: size_t, >+ ret: *mut uint8_t, >+) -> nsresult { > match (*vec).get(index) { > Some(val) => { > *ret = *val; > NS_OK >- }, >- None => NS_ERROR_INVALID_ARG >+ } >+ None => NS_ERROR_INVALID_ARG, > } > } >diff --git a/modules/libpref/parser/src/lib.rs b/modules/libpref/parser/src/lib.rs >index 8d8b9a6125e4..41c473b70218 100644 >--- a/modules/libpref/parser/src/lib.rs >+++ b/modules/libpref/parser/src/lib.rs >@@ -98,50 +98,65 @@ pub enum PrefType { > Bool, > } > > /// Keep this in sync with PrefValueKind in Preferences.h. > #[derive(Clone, Copy, Debug, PartialEq)] > #[repr(u8)] > pub enum PrefValueKind { > Default, >- User >+ User, > } > > /// Keep this in sync with PrefValue in Preferences.cpp. > #[repr(C)] > pub union PrefValue { > string_val: *const c_char, > int_val: i32, > bool_val: bool, > } > > /// Keep this in sync with PrefsParserPrefFn in Preferences.cpp. >-type PrefFn = unsafe extern "C" fn(pref_name: *const c_char, pref_type: PrefType, >- pref_value_kind: PrefValueKind, pref_value: PrefValue, >- is_sticky: bool, is_locked: bool); >+type PrefFn = unsafe extern "C" fn( >+ pref_name: *const c_char, >+ pref_type: PrefType, >+ pref_value_kind: PrefValueKind, >+ pref_value: PrefValue, >+ is_sticky: bool, >+ is_locked: bool, >+); > > /// Keep this in sync with PrefsParserErrorFn in Preferences.cpp. > type ErrorFn = unsafe extern "C" fn(msg: *const c_char); > > /// Parse the contents of a prefs file. > /// > /// `buf` is a null-terminated string. `len` is its length, excluding the > /// null terminator. > /// > /// `pref_fn` is called once for each successfully parsed pref. > /// > /// `error_fn` is called once for each parse error detected. > /// > /// Keep this in sync with the prefs_parser_parse() declaration in > /// Preferences.cpp. > #[no_mangle] >-pub extern "C" fn prefs_parser_parse(path: *const c_char, kind: PrefValueKind, buf: *const c_char, >- len: usize, pref_fn: PrefFn, error_fn: ErrorFn) -> bool { >- let path = unsafe { std::ffi::CStr::from_ptr(path).to_string_lossy().into_owned() }; >+pub extern "C" fn prefs_parser_parse( >+ path: *const c_char, >+ kind: PrefValueKind, >+ buf: *const c_char, >+ len: usize, >+ pref_fn: PrefFn, >+ error_fn: ErrorFn, >+) -> bool { >+ let path = unsafe { >+ std::ffi::CStr::from_ptr(path) >+ .to_string_lossy() >+ .into_owned() >+ }; > > // Make sure `buf` ends in a '\0', and include that in the length, because > // it represents EOF. > let buf = unsafe { std::slice::from_raw_parts(buf as *const c_uchar, len + 1) }; > assert!(buf.last() == Some(&EOF)); > > let mut parser = Parser::new(&path, kind, &buf, pref_fn, error_fn); > parser.parse() >@@ -195,104 +210,138 @@ enum CharKind { > SingleChar, // Unambiguous single-char tokens: [()+,-] > SpaceNL, // [\t\v\f \n] > Keyword, // [A-Za-z_] > Quote, // ["'] > Slash, // / > Digit, // [0-9] > Hash, // # > CR, // \r >- Other // Everything else; invalid except within strings and comments. >+ Other, // Everything else; invalid except within strings and comments. > } > > const C_SINGL: CharKind = CharKind::SingleChar; > const C_SPCNL: CharKind = CharKind::SpaceNL; > const C_KEYWD: CharKind = CharKind::Keyword; > const C_QUOTE: CharKind = CharKind::Quote; > const C_SLASH: CharKind = CharKind::Slash; > const C_DIGIT: CharKind = CharKind::Digit; >-const C_HASH : CharKind = CharKind::Hash; >-const C_CR : CharKind = CharKind::CR; >+const C_HASH: CharKind = CharKind::Hash; >+const C_CR: CharKind = CharKind::CR; > const C______: CharKind = CharKind::Other; > > const CHAR_KINDS: [CharKind; 256] = [ >-/* 0 1 2 3 4 5 6 7 8 9 */ >-/* 0+ */ C_SINGL, C______, C______, C______, C______, C______, C______, C______, C______, C_SPCNL, >-/* 10+ */ C_SPCNL, C_SPCNL, C_SPCNL, C_CR , C______, C______, C______, C______, C______, C______, >-/* 20+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 30+ */ C______, C______, C_SPCNL, C______, C_QUOTE, C_HASH , C______, C______, C______, C_QUOTE, >-/* 40+ */ C_SINGL, C_SINGL, C______, C_SINGL, C_SINGL, C_SINGL, C______, C_SLASH, C_DIGIT, C_DIGIT, >-/* 50+ */ C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C______, C_SINGL, >-/* 60+ */ C______, C______, C______, C______, C______, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 70+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 80+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 90+ */ C_KEYWD, C______, C______, C______, C______, C_KEYWD, C______, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 100+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 110+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >-/* 120+ */ C_KEYWD, C_KEYWD, C_KEYWD, C______, C______, C______, C______, C______, C______, C______, >-/* 130+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 140+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 150+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 160+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 170+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 180+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 190+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 200+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 210+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 220+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 230+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 240+ */ C______, C______, C______, C______, C______, C______, C______, C______, C______, C______, >-/* 250+ */ C______, C______, C______, C______, C______, C______ >+ /* 0 1 2 3 4 5 6 7 8 9 */ >+ /* 0+ */ >+ C_SINGL, C______, C______, C______, C______, C______, C______, C______, C______, C_SPCNL, >+ /* 10+ */ C_SPCNL, C_SPCNL, C_SPCNL, C_CR, C______, C______, C______, C______, C______, >+ C______, /* 20+ */ C______, C______, C______, C______, C______, C______, C______, >+ C______, C______, C______, /* 30+ */ C______, C______, C_SPCNL, C______, C_QUOTE, C_HASH, >+ C______, C______, C______, C_QUOTE, /* 40+ */ C_SINGL, C_SINGL, C______, C_SINGL, >+ C_SINGL, C_SINGL, C______, C_SLASH, C_DIGIT, C_DIGIT, /* 50+ */ C_DIGIT, C_DIGIT, >+ C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C_DIGIT, C______, C_SINGL, >+ /* 60+ */ C______, C______, C______, C______, C______, C_KEYWD, C_KEYWD, C_KEYWD, >+ C_KEYWD, C_KEYWD, /* 70+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >+ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, /* 80+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >+ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, /* 90+ */ C_KEYWD, C______, >+ C______, C______, C______, C_KEYWD, C______, C_KEYWD, C_KEYWD, C_KEYWD, >+ /* 100+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >+ C_KEYWD, C_KEYWD, /* 110+ */ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, >+ C_KEYWD, C_KEYWD, C_KEYWD, C_KEYWD, /* 120+ */ C_KEYWD, C_KEYWD, C_KEYWD, C______, >+ C______, C______, C______, C______, C______, C______, /* 130+ */ C______, C______, >+ C______, C______, C______, C______, C______, C______, C______, C______, >+ /* 140+ */ C______, C______, C______, C______, C______, C______, C______, C______, >+ C______, C______, /* 150+ */ C______, C______, C______, C______, C______, C______, >+ C______, C______, C______, C______, /* 160+ */ C______, C______, C______, C______, >+ C______, C______, C______, C______, C______, C______, /* 170+ */ C______, C______, >+ C______, C______, C______, C______, C______, C______, C______, C______, >+ /* 180+ */ C______, C______, C______, C______, C______, C______, C______, C______, >+ C______, C______, /* 190+ */ C______, C______, C______, C______, C______, C______, >+ C______, C______, C______, C______, /* 200+ */ C______, C______, C______, C______, >+ C______, C______, C______, C______, C______, C______, /* 210+ */ C______, C______, >+ C______, C______, C______, C______, C______, C______, C______, C______, >+ /* 220+ */ C______, C______, C______, C______, C______, C______, C______, C______, >+ C______, C______, /* 230+ */ C______, C______, C______, C______, C______, C______, >+ C______, C______, C______, C______, /* 240+ */ C______, C______, C______, C______, >+ C______, C______, C______, C______, C______, C______, /* 250+ */ C______, C______, >+ C______, C______, C______, C______, > ]; > > const _______: bool = false; > const SPECIAL_STRING_CHARS: [bool; 256] = [ >-/* 0 1 2 3 4 5 6 7 8 9 */ >-/* 0+ */ true, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 10+ */ true, _______, _______, true, _______, _______, _______, _______, _______, _______, >-/* 20+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 30+ */ _______, _______, _______, _______, true, _______, _______, _______, _______, true, >-/* 40+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 50+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 60+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 70+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 80+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 90+ */ _______, _______, true, _______, _______, _______, _______, _______, _______, _______, >-/* 100+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 110+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 120+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 130+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 140+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 150+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 160+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 170+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 180+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 190+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 200+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 210+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 220+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 230+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 240+ */ _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, >-/* 250+ */ _______, _______, _______, _______, _______, _______ >+ /* 0 1 2 3 4 5 6 7 8 9 */ >+ /* 0+ */ >+ true, _______, _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 10+ */ true, _______, _______, true, _______, _______, _______, _______, _______, >+ _______, /* 20+ */ _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, _______, /* 30+ */ _______, _______, _______, _______, true, _______, >+ _______, _______, _______, true, /* 40+ */ _______, _______, _______, _______, _______, >+ _______, _______, _______, _______, _______, /* 50+ */ _______, _______, _______, >+ _______, _______, _______, _______, _______, _______, _______, /* 60+ */ _______, >+ _______, _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 70+ */ _______, _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, /* 80+ */ _______, _______, _______, _______, _______, _______, >+ _______, _______, _______, _______, /* 90+ */ _______, _______, true, _______, _______, >+ _______, _______, _______, _______, _______, /* 100+ */ _______, _______, _______, >+ _______, _______, _______, _______, _______, _______, _______, /* 110+ */ _______, >+ _______, _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 120+ */ _______, _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, /* 130+ */ _______, _______, _______, _______, _______, _______, >+ _______, _______, _______, _______, /* 140+ */ _______, _______, _______, _______, >+ _______, _______, _______, _______, _______, _______, /* 150+ */ _______, _______, >+ _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 160+ */ _______, _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, /* 170+ */ _______, _______, _______, _______, _______, _______, >+ _______, _______, _______, _______, /* 180+ */ _______, _______, _______, _______, >+ _______, _______, _______, _______, _______, _______, /* 190+ */ _______, _______, >+ _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 200+ */ _______, _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, /* 210+ */ _______, _______, _______, _______, _______, _______, >+ _______, _______, _______, _______, /* 220+ */ _______, _______, _______, _______, >+ _______, _______, _______, _______, _______, _______, /* 230+ */ _______, _______, >+ _______, _______, _______, _______, _______, _______, _______, _______, >+ /* 240+ */ _______, _______, _______, _______, _______, _______, _______, _______, >+ _______, _______, /* 250+ */ _______, _______, _______, _______, _______, _______, > ]; > > struct KeywordInfo { >- string: &'static [u8], >- token: Token, >+ string: &'static [u8], >+ token: Token, > } > > const KEYWORD_INFOS: [KeywordInfo; 7] = [ >- // These are ordered by frequency. >- KeywordInfo { string: b"pref", token: Token::Pref }, >- KeywordInfo { string: b"true", token: Token::True }, >- KeywordInfo { string: b"false", token: Token::False }, >- KeywordInfo { string: b"user_pref", token: Token::UserPref }, >- KeywordInfo { string: b"sticky", token: Token::Sticky }, >- KeywordInfo { string: b"locked", token: Token::Locked }, >- KeywordInfo { string: b"sticky_pref", token: Token::StickyPref }, >+ // These are ordered by frequency. >+ KeywordInfo { >+ string: b"pref", >+ token: Token::Pref, >+ }, >+ KeywordInfo { >+ string: b"true", >+ token: Token::True, >+ }, >+ KeywordInfo { >+ string: b"false", >+ token: Token::False, >+ }, >+ KeywordInfo { >+ string: b"user_pref", >+ token: Token::UserPref, >+ }, >+ KeywordInfo { >+ string: b"sticky", >+ token: Token::Sticky, >+ }, >+ KeywordInfo { >+ string: b"locked", >+ token: Token::Locked, >+ }, >+ KeywordInfo { >+ string: b"sticky_pref", >+ token: Token::StickyPref, >+ }, > ]; > > struct Parser<'t> { > path: &'t str, // Path to the file being parsed. Used in error messages. > kind: PrefValueKind, // Default prefs file or user prefs file? > buf: &'t [u8], // Text being parsed. > i: usize, // Index of next char to be read. > line_num: u32, // Current line number within the text. >@@ -300,18 +349,23 @@ struct Parser<'t> { > error_fn: ErrorFn, // Callback for parse errors. > has_errors: bool, // Have we encountered errors? > } > > // As described above, we use 0 to represent EOF. > const EOF: u8 = b'\0'; > > impl<'t> Parser<'t> { >- fn new(path: &'t str, kind: PrefValueKind, buf: &'t [u8], pref_fn: PrefFn, error_fn: ErrorFn) >- -> Parser<'t> { >+ fn new( >+ path: &'t str, >+ kind: PrefValueKind, >+ buf: &'t [u8], >+ pref_fn: PrefFn, >+ error_fn: ErrorFn, >+ ) -> Parser<'t> { > // Make sure these tables take up 1 byte per entry. > assert!(std::mem::size_of_val(&CHAR_KINDS) == 256); > assert!(std::mem::size_of_val(&SPECIAL_STRING_CHARS) == 256); > > Parser { > path: path, > kind: kind, > buf: buf, >@@ -320,34 +374,36 @@ impl<'t> Parser<'t> { > pref_fn: pref_fn, > error_fn: error_fn, > has_errors: false, > } > } > > fn parse(&mut self) -> bool { > // These are reused, because allocating a new Vec for every string is slow. >- let mut name_str = Vec::with_capacity(128); // For pref names. >+ let mut name_str = Vec::with_capacity(128); // For pref names. > let mut value_str = Vec::with_capacity(512); // For string pref values. >- let mut none_str = Vec::with_capacity(0); // For tokens that shouldn't be strings. >+ let mut none_str = Vec::with_capacity(0); // For tokens that shouldn't be strings. > > let mut token = self.get_token(&mut none_str); > > // At the top of the loop we already have a token. In a valid input > // this will be either the first token of a new pref, or EOF. > loop { > // <pref-spec> > let (pref_value_kind, mut is_sticky) = match token { > Token::Pref => (PrefValueKind::Default, false), > Token::StickyPref => (PrefValueKind::Default, true), > Token::UserPref => (PrefValueKind::User, false), > Token::SingleChar(EOF) => return !self.has_errors, > _ => { > token = self.error_and_recover( >- token, "expected pref specifier at start of pref definition"); >+ token, >+ "expected pref specifier at start of pref definition", >+ ); > continue; > } > }; > > // "(" > token = self.get_token(&mut none_str); > if token != Token::SingleChar(b'(') { > token = self.error_and_recover(token, "expected '(' after pref specifier"); >@@ -368,72 +424,77 @@ impl<'t> Parser<'t> { > if token != Token::SingleChar(b',') { > token = self.error_and_recover(token, "expected ',' after pref name"); > continue; > } > > // <pref-value> > token = self.get_token(&mut value_str); > let (pref_type, pref_value) = match token { >- Token::True => { >- (PrefType::Bool, PrefValue { bool_val: true }) >- } >- Token::False => { >- (PrefType::Bool, PrefValue { bool_val: false }) >- } >- Token::String => { >- (PrefType::String, >- PrefValue { string_val: value_str.as_ptr() as *const c_char }) >- } >+ Token::True => (PrefType::Bool, PrefValue { bool_val: true }), >+ Token::False => (PrefType::Bool, PrefValue { bool_val: false }), >+ Token::String => ( >+ PrefType::String, >+ PrefValue { >+ string_val: value_str.as_ptr() as *const c_char, >+ }, >+ ), > Token::Int(u) => { > // Accept u <= 2147483647; anything larger will overflow i32. > if u <= std::i32::MAX as u32 { > (PrefType::Int, PrefValue { int_val: u as i32 }) > } else { >- token = self.error_and_recover( >- Token::Error("integer literal overflowed"), ""); >+ token = >+ self.error_and_recover(Token::Error("integer literal overflowed"), ""); > continue; > } > } > Token::SingleChar(b'-') => { > token = self.get_token(&mut none_str); > if let Token::Int(u) = token { > // Accept u <= 2147483648; anything larger will overflow i32 once negated. > if u <= std::i32::MAX as u32 { >- (PrefType::Int, PrefValue { int_val: -(u as i32) }) >+ ( >+ PrefType::Int, >+ PrefValue { >+ int_val: -(u as i32), >+ }, >+ ) > } else if u == std::i32::MAX as u32 + 1 { >- (PrefType::Int, PrefValue { int_val: std::i32::MIN }) >+ ( >+ PrefType::Int, >+ PrefValue { >+ int_val: std::i32::MIN, >+ }, >+ ) > } else { >- token = self.error_and_recover( >- Token::Error("integer literal overflowed"), ""); >+ token = self >+ .error_and_recover(Token::Error("integer literal overflowed"), ""); > continue; > } > } else { >- token = self.error_and_recover( >- token, "expected integer literal after '-'"); >+ token = self.error_and_recover(token, "expected integer literal after '-'"); > continue; > } >- > } > Token::SingleChar(b'+') => { > token = self.get_token(&mut none_str); > if let Token::Int(u) = token { > // Accept u <= 2147483647; anything larger will overflow i32. > if u <= std::i32::MAX as u32 { > (PrefType::Int, PrefValue { int_val: u as i32 }) > } else { >- token = self.error_and_recover( >- Token::Error("integer literal overflowed"), ""); >+ token = self >+ .error_and_recover(Token::Error("integer literal overflowed"), ""); > continue; > } > } else { > token = self.error_and_recover(token, "expected integer literal after '+'"); > continue; > } >- > } > _ => { > token = self.error_and_recover(token, "expected pref value after ','"); > continue; > } > }; > > // ("," <pref-attr>)* // default pref files only >@@ -449,17 +510,17 @@ impl<'t> Parser<'t> { > > // <pref-attr> > token = self.get_token(&mut none_str); > match token { > Token::Sticky => is_sticky = true, > Token::Locked => is_locked = true, > _ => { > token = >- self.error_and_recover(token, "expected pref attribute after ','"); >+ self.error_and_recover(token, "expected pref attribute after ','"); > break false; > } > } > has_attrs = true; > }; > if !ok { > continue; > } >@@ -484,18 +545,26 @@ impl<'t> Parser<'t> { > > // ";" > token = self.get_token(&mut none_str); > if token != Token::SingleChar(b';') { > token = self.error_and_recover(token, "expected ';' after ')'"); > continue; > } > >- unsafe { (self.pref_fn)(pref_name.as_ptr() as *const c_char, pref_type, pref_value_kind, >- pref_value, is_sticky, is_locked) }; >+ unsafe { >+ (self.pref_fn)( >+ pref_name.as_ptr() as *const c_char, >+ pref_type, >+ pref_value_kind, >+ pref_value, >+ is_sticky, >+ is_locked, >+ ) >+ }; > > token = self.get_token(&mut none_str); > } > } > > fn error_and_recover(&mut self, token: Token, msg: &str) -> Token { > self.has_errors = true; > >@@ -587,24 +656,23 @@ impl<'t> Parser<'t> { > self.match_char(b'\n'); > break; > } > EOF => { > // Unget EOF so subsequent calls to get_char() are safe. > self.unget_char(); > break; > } >- _ => continue >+ _ => continue, > } > } > } > > // Returns false if we hit EOF without closing the comment. >- fn match_multi_line_comment(&mut self) -> bool >- { >+ fn match_multi_line_comment(&mut self) -> bool { > loop { > match self.get_char() { > b'*' => { > if self.match_char(b'/') { > return true; > } > } > b'\n' => { >@@ -612,30 +680,30 @@ impl<'t> Parser<'t> { > } > b'\r' => { > self.line_num += 1; > self.match_char(b'\n'); > } > EOF => { > // Unget EOF so subsequent calls to get_char() are safe. > self.unget_char(); >- return false >+ return false; > } >- _ => continue >+ _ => continue, > } > } > } > > fn match_hex_digits(&mut self, ndigits: i32) -> Option<u16> { > debug_assert!(ndigits == 2 || ndigits == 4); > let mut value: u16 = 0; > for _ in 0..ndigits { > value = value << 4; > match self.get_char() { >- c @ b'0'... b'9' => value += (c - b'0') as u16, >+ c @ b'0'...b'9' => value += (c - b'0') as u16, > c @ b'A'...b'F' => value += (c - b'A') as u16 + 10, > c @ b'a'...b'f' => value += (c - b'a') as u16 + 10, > _ => { > // Unget in case the char was a closing quote or EOF. > self.unget_char(); > return None; > } > } >@@ -711,17 +779,17 @@ impl<'t> Parser<'t> { > b'/' => { > self.match_single_line_comment(); > } > b'*' => { > if !self.match_multi_line_comment() { > return Token::Error("unterminated /* comment"); > } > } >- _ => return Token::Error("expected '/' or '*' after '/'") >+ _ => return Token::Error("expected '/' or '*' after '/'"), > } > continue; > } > CharKind::Digit => { > let mut value = Some((c - b'0') as u32); > loop { > let c = self.get_char(); > match Parser::char_kind(c) { >@@ -753,17 +821,17 @@ impl<'t> Parser<'t> { > continue; > } > CharKind::CR => { > self.match_char(b'\n'); > self.line_num += 1; > continue; > } > // Error recovery will retokenize from the next character. >- _ => return Token::Error("unexpected character") >+ _ => return Token::Error("unexpected character"), > } > } > } > > fn string_error_token(&self, token: &mut Token, msg: &'static str) { > // We only want to capture the first tokenization error within a string. > if *token == Token::String { > *token = Token::ErrorAtLine(msg, self.line_num); >@@ -787,45 +855,43 @@ impl<'t> Parser<'t> { > }; > > // Clear str_buf's contents without changing its capacity. > str_buf.clear(); > > // If there are no special chars (the common case), we can bulk copy it > // to str_buf. This is a lot faster than the char-by-char loop below. > if !has_special_chars { >- str_buf.extend(&self.buf[start..self.i - 1]); >- str_buf.push(b'\0'); >- return Token::String; >+ str_buf.extend(&self.buf[start..self.i - 1]); >+ str_buf.push(b'\0'); >+ return Token::String; > } > > // There were special chars. Re-scan the string, filling in str_buf one > // char at a time. > // > // On error, we change `token` to an error token and then keep going to > // the end of the string literal. `str_buf` won't be used in that case. > self.i = start; > let mut token = Token::String; > > loop { > let c = self.get_char(); > let c2 = if !Parser::is_special_string_char(c) { > c >- > } else if c == quote_char { > break; >- > } else if c == b'\\' { > match self.get_char() { > b'\"' => b'\"', > b'\'' => b'\'', > b'\\' => b'\\', >- b'n' => b'\n', >- b'r' => b'\r', >- b'x' => { >+ b'n' => b'\n', >+ b'r' => b'\r', >+ b'x' => { > if let Some(value) = self.match_hex_digits(2) { > debug_assert!(value <= 0xff); > if value != 0 { > value as u8 > } else { > self.string_error_token(&mut token, "\\x00 is not allowed"); > continue; > } >@@ -842,24 +908,27 @@ impl<'t> Parser<'t> { > if self.match_char(b'\\') && self.match_char(b'u') { > if let Some(lo) = self.match_hex_digits(4) { > if 0xdc00 == (0xfc00 & lo) { > // Found a valid low surrogate. > utf16.push(lo); > } else { > self.string_error_token( > &mut token, >- "invalid low surrogate value after high surrogate"); >+ "invalid low surrogate value after high surrogate", >+ ); > continue; > } > } > } > if utf16.len() != 2 { > self.string_error_token( >- &mut token, "expected low surrogate after high surrogate"); >+ &mut token, >+ "expected low surrogate after high surrogate", >+ ); > continue; > } > } else if value == 0 { > self.string_error_token(&mut token, "\\u0000 is not allowed"); > continue; > } > > // Insert the UTF-16 sequence as UTF-8. >@@ -870,40 +939,38 @@ impl<'t> Parser<'t> { > continue; > } > continue; // We don't want to str_buf.push(c2) below. > } > _ => { > // Unget in case the char is an EOF. > self.unget_char(); > self.string_error_token( >- &mut token, "unexpected escape sequence character after '\\'"); >+ &mut token, >+ "unexpected escape sequence character after '\\'", >+ ); > continue; > } > } >- > } else if c == b'\n' { > self.line_num += 1; > c >- > } else if c == b'\r' { > self.line_num += 1; > if self.match_char(b'\n') { > str_buf.push(b'\r'); > b'\n' > } else { > c > } >- > } else if c == EOF { > // Unget EOF so subsequent calls to get_char() are safe. > self.unget_char(); > self.string_error_token(&mut token, "unterminated string literal"); > break; >- > } else { > // This case is only hit for the non-closing quote char. > debug_assert!((c == b'\'' || c == b'\"') && c != quote_char); > c > }; > str_buf.push(c2); > } > str_buf.push(b'\0'); >diff --git a/netwerk/base/mozurl/src/lib.rs b/netwerk/base/mozurl/src/lib.rs >index 87392e0993b0..ce06790caa4c 100644 >--- a/netwerk/base/mozurl/src/lib.rs >+++ b/netwerk/base/mozurl/src/lib.rs >@@ -1,412 +1,417 @@ > /* -*- Mode: rust; rust-indent-offset: 2 -*- */ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > extern crate url; >-use url::{Url, ParseOptions, Position}; > use url::quirks; >+use url::{ParseOptions, Position, Url}; > > extern crate nsstring; >-use nsstring::{nsCString, nsACString}; >+use nsstring::{nsACString, nsCString}; > > extern crate nserror; > use nserror::*; > > extern crate xpcom; >-use xpcom::{AtomicRefcnt, RefPtr, RefCounted}; > use xpcom::interfaces::nsrefcnt; >+use xpcom::{AtomicRefcnt, RefCounted, RefPtr}; > >-use std::str; >-use std::ptr; >-use std::ops; >-use std::marker::PhantomData; > use std::fmt::Write; >+use std::marker::PhantomData; >+use std::ops; >+use std::ptr; >+use std::str; > > /// Helper macro. If the expression $e is Ok(t) evaluates to t, otherwise, > /// returns NS_ERROR_MALFORMED_URI. > macro_rules! try_or_malformed { >- ($e:expr) => ( >- match $e { >- Ok(v) => v, >- Err(_) => return NS_ERROR_MALFORMED_URI, >- } >- ) >+ ($e:expr) => { >+ match $e { >+ Ok(v) => v, >+ Err(_) => return NS_ERROR_MALFORMED_URI, >+ } >+ }; > } > > fn parser<'a>() -> ParseOptions<'a> { >- Url::options() >+ Url::options() > } > > fn default_port(scheme: &str) -> Option<u16> { >- match scheme { >- "ftp" => Some(21), >- "gopher" => Some(70), >- "http" => Some(80), >- "https" => Some(443), >- "ws" => Some(80), >- "wss" => Some(443), >- "rtsp" => Some(443), >- "moz-anno" => Some(443), >- "android" => Some(443), >- _ => None, >- } >+ match scheme { >+ "ftp" => Some(21), >+ "gopher" => Some(70), >+ "http" => Some(80), >+ "https" => Some(443), >+ "ws" => Some(80), >+ "wss" => Some(443), >+ "rtsp" => Some(443), >+ "moz-anno" => Some(443), >+ "android" => Some(443), >+ _ => None, >+ } > } > > /// A slice into the backing string. This type is only valid as long as the > /// MozURL which it was pulled from is valid. In C++, this type implicitly > /// converts to a nsDependentCString, and is an implementation detail. > /// > /// This type exists because, unlike &str, this type is safe to return over FFI. > #[repr(C)] > pub struct SpecSlice<'a> { >- data: *const u8, >- len: u32, >- _marker: PhantomData<&'a [u8]>, >+ data: *const u8, >+ len: u32, >+ _marker: PhantomData<&'a [u8]>, > } > > impl<'a> From<&'a str> for SpecSlice<'a> { >- fn from(s: &'a str) -> SpecSlice<'a> { >- assert!(s.len() < u32::max_value() as usize); >- SpecSlice { >- data: s.as_ptr(), >- len: s.len() as u32, >- _marker: PhantomData, >+ fn from(s: &'a str) -> SpecSlice<'a> { >+ assert!(s.len() < u32::max_value() as usize); >+ SpecSlice { >+ data: s.as_ptr(), >+ len: s.len() as u32, >+ _marker: PhantomData, >+ } > } >- } > } > > /// The MozURL reference-counted threadsafe URL type. This type intentionally > /// implements no XPCOM interfaces, and all method calls are non-virtual. > #[repr(C)] > pub struct MozURL { >- pub url: Url, >- refcnt: AtomicRefcnt, >+ pub url: Url, >+ refcnt: AtomicRefcnt, > } > > impl MozURL { >- pub fn from_url(url: Url) -> RefPtr<MozURL> { >- // Actually allocate the URL on the heap. This is the only place we actually >- // create a MozURL, other than in clone(). >- unsafe { >- RefPtr::from_raw(Box::into_raw(Box::new(MozURL { >- url: url, >- refcnt: AtomicRefcnt::new(), >- }))).unwrap() >+ pub fn from_url(url: Url) -> RefPtr<MozURL> { >+ // Actually allocate the URL on the heap. This is the only place we actually >+ // create a MozURL, other than in clone(). >+ unsafe { >+ RefPtr::from_raw(Box::into_raw(Box::new(MozURL { >+ url: url, >+ refcnt: AtomicRefcnt::new(), >+ }))).unwrap() >+ } > } >- } > } > > impl ops::Deref for MozURL { >- type Target = Url; >- fn deref(&self) -> &Url { >- &self.url >- } >+ type Target = Url; >+ fn deref(&self) -> &Url { >+ &self.url >+ } > } > impl ops::DerefMut for MozURL { >- fn deref_mut(&mut self) -> &mut Url { >- &mut self.url >- } >+ fn deref_mut(&mut self) -> &mut Url { >+ &mut self.url >+ } > } > > // Memory Management for MozURL > #[no_mangle] > pub unsafe extern "C" fn mozurl_addref(url: &MozURL) -> nsrefcnt { >- url.refcnt.inc() >+ url.refcnt.inc() > } > > #[no_mangle] > pub unsafe extern "C" fn mozurl_release(url: &MozURL) -> nsrefcnt { >- let rc = url.refcnt.dec(); >- if rc == 0 { >- Box::from_raw(url as *const MozURL as *mut MozURL); >- } >- rc >+ let rc = url.refcnt.dec(); >+ if rc == 0 { >+ Box::from_raw(url as *const MozURL as *mut MozURL); >+ } >+ rc > } > > // xpcom::RefPtr support > unsafe impl RefCounted for MozURL { >- unsafe fn addref(&self) { >- mozurl_addref(self); >- } >- unsafe fn release(&self) { >- mozurl_release(self); >- } >+ unsafe fn addref(&self) { >+ mozurl_addref(self); >+ } >+ unsafe fn release(&self) { >+ mozurl_release(self); >+ } > } > > // Allocate a new MozURL object with a RefCnt of 1, and store a pointer to it > // into url. > #[no_mangle] > pub extern "C" fn mozurl_new( >- result: &mut *const MozURL, >- spec: &nsACString, >- base: Option<&MozURL>, >+ result: &mut *const MozURL, >+ spec: &nsACString, >+ base: Option<&MozURL>, > ) -> nsresult { >- *result = ptr::null_mut(); >+ *result = ptr::null_mut(); > >- let spec = try_or_malformed!(str::from_utf8(spec)); >- let url = if let Some(base) = base { >- try_or_malformed!(base.url.join(spec)) >- } else { >- try_or_malformed!(parser().parse(spec)) >- }; >+ let spec = try_or_malformed!(str::from_utf8(spec)); >+ let url = if let Some(base) = base { >+ try_or_malformed!(base.url.join(spec)) >+ } else { >+ try_or_malformed!(parser().parse(spec)) >+ }; > >- MozURL::from_url(url).forget(result); >- NS_OK >+ MozURL::from_url(url).forget(result); >+ NS_OK > } > > /// Allocate a new MozURL object which is a clone of the original, and store a > /// pointer to it into newurl. > #[no_mangle] > pub extern "C" fn mozurl_clone(url: &MozURL, newurl: &mut *const MozURL) { >- MozURL::from_url(url.url.clone()).forget(newurl); >+ MozURL::from_url(url.url.clone()).forget(newurl); > } > > #[no_mangle] > pub extern "C" fn mozurl_spec(url: &MozURL) -> SpecSlice { >- url.as_ref().into() >+ url.as_ref().into() > } > > #[no_mangle] > pub extern "C" fn mozurl_scheme(url: &MozURL) -> SpecSlice { >- url.scheme().into() >+ url.scheme().into() > } > > #[no_mangle] > pub extern "C" fn mozurl_username(url: &MozURL) -> SpecSlice { >- if url.cannot_be_a_base() { >- "".into() >- } else { >- url.username().into() >- } >+ if url.cannot_be_a_base() { >+ "".into() >+ } else { >+ url.username().into() >+ } > } > > #[no_mangle] > pub extern "C" fn mozurl_password(url: &MozURL) -> SpecSlice { >- url.password().unwrap_or("").into() >+ url.password().unwrap_or("").into() > } > > #[no_mangle] > pub extern "C" fn mozurl_host(url: &MozURL) -> SpecSlice { >- url.host_str().unwrap_or("").into() >+ url.host_str().unwrap_or("").into() > } > > #[no_mangle] > pub extern "C" fn mozurl_port(url: &MozURL) -> i32 { >- // NOTE: Gecko uses -1 to represent the default port. >- url.port().map(|p| p as i32).unwrap_or(-1) >+ // NOTE: Gecko uses -1 to represent the default port. >+ url.port().map(|p| p as i32).unwrap_or(-1) > } > > #[no_mangle] > pub extern "C" fn mozurl_host_port(url: &MozURL) -> SpecSlice { >- (&url[Position::BeforeHost..Position::BeforePath]).into() >+ (&url[Position::BeforeHost..Position::BeforePath]).into() > } > > #[no_mangle] > pub extern "C" fn mozurl_filepath(url: &MozURL) -> SpecSlice { >- url.path().into() >+ url.path().into() > } > > #[no_mangle] > pub extern "C" fn mozurl_path(url: &MozURL) -> SpecSlice { >- (&url[Position::BeforePath..]).into() >+ (&url[Position::BeforePath..]).into() > } > > #[no_mangle] > pub extern "C" fn mozurl_query(url: &MozURL) -> SpecSlice { >- url.query().unwrap_or("").into() >+ url.query().unwrap_or("").into() > } > > #[no_mangle] > pub extern "C" fn mozurl_fragment(url: &MozURL) -> SpecSlice { >- url.fragment().unwrap_or("").into() >+ url.fragment().unwrap_or("").into() > } > > #[no_mangle] > pub extern "C" fn mozurl_has_fragment(url: &MozURL) -> bool { >- url.fragment().is_some() >+ url.fragment().is_some() > } > > #[no_mangle] > pub extern "C" fn mozurl_origin(url: &MozURL, origin: &mut nsACString) { >- // NOTE: Try to re-use the allocation we got from rust-url, and transfer >- // ownership of the buffer to C++. >- let mut o = nsCString::from(url.origin().ascii_serialization()); >- origin.take_from(&mut o); >+ // NOTE: Try to re-use the allocation we got from rust-url, and transfer >+ // ownership of the buffer to C++. >+ let mut o = nsCString::from(url.origin().ascii_serialization()); >+ origin.take_from(&mut o); > } > > // Helper macro for debug asserting that we're the only reference to MozURL. > macro_rules! debug_assert_mut { >- ($e:expr) => { >- debug_assert_eq!( >- $e.refcnt.get(), 1, >- "Cannot mutate an aliased MozURL!" >- ); >- } >+ ($e:expr) => { >+ debug_assert_eq!($e.refcnt.get(), 1, "Cannot mutate an aliased MozURL!"); >+ }; > } > > #[no_mangle] > pub extern "C" fn mozurl_set_scheme(url: &mut MozURL, scheme: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let scheme = try_or_malformed!(str::from_utf8(scheme)); >- try_or_malformed!(quirks::set_protocol(url, scheme)); >- NS_OK >+ debug_assert_mut!(url); >+ let scheme = try_or_malformed!(str::from_utf8(scheme)); >+ try_or_malformed!(quirks::set_protocol(url, scheme)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_username(url: &mut MozURL, username: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let username = try_or_malformed!(str::from_utf8(username)); >- try_or_malformed!(quirks::set_username(url, username)); >- NS_OK >+ debug_assert_mut!(url); >+ let username = try_or_malformed!(str::from_utf8(username)); >+ try_or_malformed!(quirks::set_username(url, username)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_password(url: &mut MozURL, password: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let password = try_or_malformed!(str::from_utf8(password)); >- try_or_malformed!(quirks::set_password(url, password)); >- NS_OK >+ debug_assert_mut!(url); >+ let password = try_or_malformed!(str::from_utf8(password)); >+ try_or_malformed!(quirks::set_password(url, password)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_host_port(url: &mut MozURL, hostport: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let hostport = try_or_malformed!(str::from_utf8(hostport)); >- try_or_malformed!(quirks::set_host(url, hostport)); >- NS_OK >+ debug_assert_mut!(url); >+ let hostport = try_or_malformed!(str::from_utf8(hostport)); >+ try_or_malformed!(quirks::set_host(url, hostport)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_hostname(url: &mut MozURL, host: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let host = try_or_malformed!(str::from_utf8(host)); >- try_or_malformed!(quirks::set_hostname(url, host)); >- NS_OK >+ debug_assert_mut!(url); >+ let host = try_or_malformed!(str::from_utf8(host)); >+ try_or_malformed!(quirks::set_hostname(url, host)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_port_no(url: &mut MozURL, new_port: i32) -> nsresult { >- debug_assert_mut!(url); >- if url.cannot_be_a_base() { >- return NS_ERROR_MALFORMED_URI; >- } >+ debug_assert_mut!(url); >+ if url.cannot_be_a_base() { >+ return NS_ERROR_MALFORMED_URI; >+ } > >- let port = match new_port { >- new if new < 0 || u16::max_value() as i32 > new => None, >- new if Some(new as u16) == default_port(url.scheme()) => None, >- new => Some(new as u16), >- }; >- try_or_malformed!(url.set_port(port)); >- NS_OK >+ let port = match new_port { >+ new if new < 0 || u16::max_value() as i32 > new => None, >+ new if Some(new as u16) == default_port(url.scheme()) => None, >+ new => Some(new as u16), >+ }; >+ try_or_malformed!(url.set_port(port)); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_pathname(url: &mut MozURL, path: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let path = try_or_malformed!(str::from_utf8(path)); >- quirks::set_pathname(url, path); >- NS_OK >+ debug_assert_mut!(url); >+ let path = try_or_malformed!(str::from_utf8(path)); >+ quirks::set_pathname(url, path); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_query(url: &mut MozURL, query: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let query = try_or_malformed!(str::from_utf8(query)); >- quirks::set_search(url, query); >- NS_OK >+ debug_assert_mut!(url); >+ let query = try_or_malformed!(str::from_utf8(query)); >+ quirks::set_search(url, query); >+ NS_OK > } > > #[no_mangle] > pub extern "C" fn mozurl_set_fragment(url: &mut MozURL, fragment: &nsACString) -> nsresult { >- debug_assert_mut!(url); >- let fragment = try_or_malformed!(str::from_utf8(fragment)); >- quirks::set_hash(url, fragment); >- NS_OK >+ debug_assert_mut!(url); >+ let fragment = try_or_malformed!(str::from_utf8(fragment)); >+ quirks::set_hash(url, fragment); >+ NS_OK > } > > #[no_mangle] >-pub extern "C" fn mozurl_common_base(url1: &MozURL, url2: &MozURL, result: &mut *const MozURL) -> nsresult { >- *result = ptr::null(); >- if url1.url == url2.url { >- RefPtr::new(url1).forget(result); >- return NS_OK; >- } >- >- if url1.scheme() != url2.scheme() || >- url1.host() != url2.host() || >- url1.username() != url2.username() || >- url1.password() != url2.password() || >- url1.port() != url2.port() { >- return NS_OK; >- } >+pub extern "C" fn mozurl_common_base( >+ url1: &MozURL, >+ url2: &MozURL, >+ result: &mut *const MozURL, >+) -> nsresult { >+ *result = ptr::null(); >+ if url1.url == url2.url { >+ RefPtr::new(url1).forget(result); >+ return NS_OK; >+ } > >- match (url1.path_segments(), url2.path_segments()) { >- (Some(path1), Some(path2)) => { >- // Take the shared prefix of path segments >- let mut url = url1.url.clone(); >- if let Ok(mut segs) = url.path_segments_mut() { >- segs.clear(); >- segs.extend(path1.zip(path2) >- .take_while(|&(a, b)| a == b) >- .map(|p| p.0)); >- } else { >+ if url1.scheme() != url2.scheme() >+ || url1.host() != url2.host() >+ || url1.username() != url2.username() >+ || url1.password() != url2.password() >+ || url1.port() != url2.port() >+ { > return NS_OK; >- } >+ } > >- MozURL::from_url(url).forget(result); >- NS_OK >+ match (url1.path_segments(), url2.path_segments()) { >+ (Some(path1), Some(path2)) => { >+ // Take the shared prefix of path segments >+ let mut url = url1.url.clone(); >+ if let Ok(mut segs) = url.path_segments_mut() { >+ segs.clear(); >+ segs.extend(path1.zip(path2).take_while(|&(a, b)| a == b).map(|p| p.0)); >+ } else { >+ return NS_OK; >+ } >+ >+ MozURL::from_url(url).forget(result); >+ NS_OK >+ } >+ _ => NS_OK, > } >- _ => NS_OK, >- } > } > > #[no_mangle] >-pub extern "C" fn mozurl_relative(url1: &MozURL, url2: &MozURL, result: &mut nsACString) -> nsresult { >- if url1.url == url2.url { >- result.truncate(); >- return NS_OK; >- } >+pub extern "C" fn mozurl_relative( >+ url1: &MozURL, >+ url2: &MozURL, >+ result: &mut nsACString, >+) -> nsresult { >+ if url1.url == url2.url { >+ result.truncate(); >+ return NS_OK; >+ } > >- if url1.scheme() != url2.scheme() || >- url1.host() != url2.host() || >- url1.username() != url2.username() || >- url1.password() != url2.password() || >- url1.port() != url2.port() { >- result.assign(url2.as_ref()); >- return NS_OK; >- } >+ if url1.scheme() != url2.scheme() >+ || url1.host() != url2.host() >+ || url1.username() != url2.username() >+ || url1.password() != url2.password() >+ || url1.port() != url2.port() >+ { >+ result.assign(url2.as_ref()); >+ return NS_OK; >+ } > >- match (url1.path_segments(), url2.path_segments()) { >- (Some(mut path1), Some(mut path2)) => { >- // Exhaust the part of the iterators that match >- while let (Some(ref p1), Some(ref p2)) = (path1.next(), path2.next()) { >- if p1 != p2 { >- break; >- } >- } >+ match (url1.path_segments(), url2.path_segments()) { >+ (Some(mut path1), Some(mut path2)) => { >+ // Exhaust the part of the iterators that match >+ while let (Some(ref p1), Some(ref p2)) = (path1.next(), path2.next()) { >+ if p1 != p2 { >+ break; >+ } >+ } > >- result.truncate(); >- for _ in path1 { >- result.append("../"); >- } >- for p2 in path2 { >- result.append(p2); >- result.append("/"); >- } >- } >- _ => { >- result.assign(url2.as_ref()); >+ result.truncate(); >+ for _ in path1 { >+ result.append("../"); >+ } >+ for p2 in path2 { >+ result.append(p2); >+ result.append("/"); >+ } >+ } >+ _ => { >+ result.assign(url2.as_ref()); >+ } > } >- } >- NS_OK >+ NS_OK > } > > /// This type is used by nsStandardURL > #[no_mangle] > pub extern "C" fn rusturl_parse_ipv6addr(input: &nsACString, addr: &mut nsACString) -> nsresult { >- let ip6 = try_or_malformed!(str::from_utf8(input)); >- let host = try_or_malformed!(url::Host::parse(ip6)); >- let _ = write!(addr, "{}", host); >- NS_OK >+ let ip6 = try_or_malformed!(str::from_utf8(input)); >+ let host = try_or_malformed!(url::Host::parse(ip6)); >+ let _ = write!(addr, "{}", host); >+ NS_OK > } >diff --git a/netwerk/base/rust-helper/src/lib.rs b/netwerk/base/rust-helper/src/lib.rs >index 24455e097a2a..2845c6ebbe13 100644 >--- a/netwerk/base/rust-helper/src/lib.rs >+++ b/netwerk/base/rust-helper/src/lib.rs >@@ -6,17 +6,18 @@ use self::nsstring::nsACString; > > /// HTTP leading whitespace, defined in netwerk/protocol/http/nsHttp.h > static HTTP_LWS: &'static [u8] = &[' ' as u8, '\t' as u8]; > > /// Trim leading whitespace, trailing whitespace, and quality-value > /// from a token. > fn trim_token(token: &[u8]) -> &[u8] { > // Trim left whitespace >- let ltrim = token.iter() >+ let ltrim = token >+ .iter() > .take_while(|c| HTTP_LWS.iter().any(|ws| &ws == c)) > .count(); > > // Trim right whitespace > // remove "; q=..." if present > let rtrim = token[ltrim..] > .iter() > .take_while(|c| **c != (';' as u8) && HTTP_LWS.iter().all(|ws| ws != *c)) >@@ -33,33 +34,34 @@ fn trim_token(token: &[u8]) -> &[u8] { > /// the langs implies the q value. The q values are calculated by dividing > /// 1.0 amongst the number of languages present. > /// > /// Ex: passing: "en, ja" > /// returns: "en,ja;q=0.5" > /// > /// passing: "en, ja, fr_CA" > /// returns: "en,ja;q=0.7,fr_CA;q=0.3" >-pub extern "C" fn rust_prepare_accept_languages<'a, 'b>(i_accept_languages: &'a nsACString, >- o_accept_languages: &'b mut nsACString) >- -> nsresult { >+pub extern "C" fn rust_prepare_accept_languages<'a, 'b>( >+ i_accept_languages: &'a nsACString, >+ o_accept_languages: &'b mut nsACString, >+) -> nsresult { > if i_accept_languages.is_empty() { > return NS_OK; > } > > let make_tokens = || { >- i_accept_languages.split(|c| *c == (',' as u8)) >+ i_accept_languages >+ .split(|c| *c == (',' as u8)) > .map(|token| trim_token(token)) > .filter(|token| token.len() != 0) > }; > > let n = make_tokens().count(); > > for (count_n, i_token) in make_tokens().enumerate() { >- > // delimiter if not first item > if count_n != 0 { > o_accept_languages.append(","); > } > > let token_pos = o_accept_languages.len(); > o_accept_languages.append(&i_token as &[u8]); > >@@ -125,17 +127,17 @@ fn canonicalize_language_tag(token: &mut [u8]) { > // Singleton tag, like "x" or "i". These signify a > // non-standard language, so we stop capitalizing after > // these. > 1 => break, > // ISO 3166-1 Country code, like "US" > 2 => { > sub_tag[0] = sub_tag[0].to_ascii_uppercase(); > sub_tag[1] = sub_tag[1].to_ascii_uppercase(); >- }, >+ } > // ISO 15924 script code, like "Nkoo" >- 4 => { >+ 4 => { > sub_tag[0] = sub_tag[0].to_ascii_uppercase(); >- }, >- _ => {}, >+ } >+ _ => {} > }; > } > } >diff --git a/servo/components/fallible/lib.rs b/servo/components/fallible/lib.rs >index c220699a7861..f807bc9ce7a6 100644 >--- a/servo/components/fallible/lib.rs >+++ b/servo/components/fallible/lib.rs >@@ -1,29 +1,28 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > extern crate hashglobe; > extern crate smallvec; > >-use hashglobe::FailedAllocationError; > #[cfg(feature = "known_system_malloc")] > use hashglobe::alloc; >+use hashglobe::FailedAllocationError; > use smallvec::Array; > use smallvec::SmallVec; > use std::vec::Vec; > > pub trait FallibleVec<T> { > /// Append |val| to the end of |vec|. Returns Ok(()) on success, > /// Err(reason) if it fails, with |reason| describing the failure. > fn try_push(&mut self, value: T) -> Result<(), FailedAllocationError>; > } > >- > ///////////////////////////////////////////////////////////////// > // Vec > > impl<T> FallibleVec<T> for Vec<T> { > #[inline(always)] > fn try_push(&mut self, val: T) -> Result<(), FailedAllocationError> { > #[cfg(feature = "known_system_malloc")] > { >@@ -47,48 +46,45 @@ fn try_double_vec<T>(vec: &mut Vec<T>) -> Result<(), FailedAllocationError> { > > let old_ptr = vec.as_mut_ptr(); > let old_len = vec.len(); > > let old_cap: usize = vec.capacity(); > let new_cap: usize = if old_cap == 0 { > 4 > } else { >- old_cap.checked_mul(2).ok_or(FailedAllocationError::new( >- "capacity overflow for Vec", >- ))? >+ old_cap >+ .checked_mul(2) >+ .ok_or(FailedAllocationError::new("capacity overflow for Vec"))? > }; > >- let new_size_bytes = new_cap.checked_mul(mem::size_of::<T>()).ok_or( >- FailedAllocationError::new("capacity overflow for Vec"), >- )?; >+ let new_size_bytes = new_cap >+ .checked_mul(mem::size_of::<T>()) >+ .ok_or(FailedAllocationError::new("capacity overflow for Vec"))?; > > let new_ptr = unsafe { > if old_cap == 0 { > alloc::alloc(new_size_bytes, 0) > } else { > alloc::realloc(old_ptr as *mut u8, new_size_bytes) > } > }; > > if new_ptr.is_null() { > return Err(FailedAllocationError::new( > "out of memory when allocating Vec", > )); > } > >- let new_vec = unsafe { >- Vec::from_raw_parts(new_ptr as *mut T, old_len, new_cap) >- }; >+ let new_vec = unsafe { Vec::from_raw_parts(new_ptr as *mut T, old_len, new_cap) }; > > mem::forget(mem::replace(vec, new_vec)); > Ok(()) > } > >- > ///////////////////////////////////////////////////////////////// > // SmallVec > > impl<T: Array> FallibleVec<T::Item> for SmallVec<T> { > #[inline(always)] > fn try_push(&mut self, val: T::Item) -> Result<(), FailedAllocationError> { > #[cfg(feature = "known_system_malloc")] > { >@@ -102,70 +98,66 @@ impl<T: Array> FallibleVec<T::Item> for SmallVec<T> { > } > } > > // Double the capacity of |svec|, or fail to do so due to lack of memory. > // Returns Ok(()) on success, Err(..) on failure. > #[cfg(feature = "known_system_malloc")] > #[inline(never)] > #[cold] >-fn try_double_small_vec<T>(svec: &mut SmallVec<T>) >--> Result<(), FailedAllocationError> >+fn try_double_small_vec<T>(svec: &mut SmallVec<T>) -> Result<(), FailedAllocationError> > where > T: Array, > { > use std::mem; > use std::ptr::copy_nonoverlapping; > > let old_ptr = svec.as_mut_ptr(); > let old_len = svec.len(); > > let old_cap: usize = svec.capacity(); > let new_cap: usize = if old_cap == 0 { > 4 > } else { >- old_cap.checked_mul(2).ok_or(FailedAllocationError::new( >- "capacity overflow for SmallVec", >- ))? >+ old_cap >+ .checked_mul(2) >+ .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))? > }; > > // This surely shouldn't fail, if |old_cap| was previously accepted as a > // valid value. But err on the side of caution. >- let old_size_bytes = old_cap.checked_mul(mem::size_of::<T>()).ok_or( >- FailedAllocationError::new("capacity overflow for SmallVec"), >- )?; >+ let old_size_bytes = old_cap >+ .checked_mul(mem::size_of::<T>()) >+ .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))?; > >- let new_size_bytes = new_cap.checked_mul(mem::size_of::<T>()).ok_or( >- FailedAllocationError::new("capacity overflow for SmallVec"), >- )?; >+ let new_size_bytes = new_cap >+ .checked_mul(mem::size_of::<T>()) >+ .ok_or(FailedAllocationError::new("capacity overflow for SmallVec"))?; > > let new_ptr; > if svec.spilled() { > // There's an old block to free, and, presumably, old contents to > // copy. realloc takes care of both aspects. > unsafe { > new_ptr = alloc::realloc(old_ptr as *mut u8, new_size_bytes); > } > } else { > // There's no old block to free. There may be old contents to copy. > unsafe { > new_ptr = alloc::alloc(new_size_bytes, 0); > if !new_ptr.is_null() && old_size_bytes > 0 { >- copy_nonoverlapping(old_ptr as *const u8, >- new_ptr as *mut u8, old_size_bytes); >+ copy_nonoverlapping(old_ptr as *const u8, new_ptr as *mut u8, old_size_bytes); > } > } > } > > if new_ptr.is_null() { > return Err(FailedAllocationError::new( > "out of memory when allocating SmallVec", > )); > } > >- let new_vec = unsafe { >- Vec::from_raw_parts(new_ptr as *mut T::Item, old_len, new_cap) >- }; >+ let new_vec = unsafe { Vec::from_raw_parts(new_ptr as *mut T::Item, old_len, new_cap) }; > > let new_svec = SmallVec::from_vec(new_vec); > mem::forget(mem::replace(svec, new_svec)); > Ok(()) > } >diff --git a/servo/components/hashglobe/src/alloc.rs b/servo/components/hashglobe/src/alloc.rs >index b0d622972db1..b1c7a6eca5ee 100644 >--- a/servo/components/hashglobe/src/alloc.rs >+++ b/servo/components/hashglobe/src/alloc.rs >@@ -1,30 +1,31 @@ > // FORK NOTE: Copied from liballoc_system, removed unnecessary APIs, > // APIs take size/align directly instead of Layout > >- >- >- > // The minimum alignment guaranteed by the architecture. This value is used to > // add fast paths for low alignment values. In practice, the alignment is a > // constant at the call site and the branch will be optimized out. >-#[cfg(all(any(target_arch = "x86", >- target_arch = "arm", >- target_arch = "mips", >- target_arch = "powerpc", >- target_arch = "powerpc64", >- target_arch = "asmjs", >- target_arch = "wasm32")))] >+#[cfg(all(any( >+ target_arch = "x86", >+ target_arch = "arm", >+ target_arch = "mips", >+ target_arch = "powerpc", >+ target_arch = "powerpc64", >+ target_arch = "asmjs", >+ target_arch = "wasm32" >+)))] > const MIN_ALIGN: usize = 8; >-#[cfg(all(any(target_arch = "x86_64", >- target_arch = "aarch64", >- target_arch = "mips64", >- target_arch = "s390x", >- target_arch = "sparc64")))] >+#[cfg(all(any( >+ target_arch = "x86_64", >+ target_arch = "aarch64", >+ target_arch = "mips64", >+ target_arch = "s390x", >+ target_arch = "sparc64" >+)))] > const MIN_ALIGN: usize = 16; > > pub use self::platform::{alloc, dealloc, realloc}; > > #[cfg(any(unix, target_os = "redox"))] > mod platform { > extern crate libc; > >@@ -95,17 +96,16 @@ mod platform { > > use super::MIN_ALIGN; > type LPVOID = *mut u8; > type HANDLE = LPVOID; > type SIZE_T = usize; > type DWORD = u32; > type BOOL = i32; > >- > extern "system" { > fn GetProcessHeap() -> HANDLE; > fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID; > fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID; > fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL; > fn GetLastError() -> DWORD; > } > >@@ -118,18 +118,17 @@ mod platform { > > unsafe fn align_ptr(ptr: *mut u8, align: usize) -> *mut u8 { > let aligned = ptr.offset((align - (ptr as usize & (align - 1))) as isize); > *get_header(aligned) = Header(ptr); > aligned > } > > #[inline] >- unsafe fn allocate_with_flags(size: usize, align: usize, flags: DWORD) -> *mut u8 >- { >+ unsafe fn allocate_with_flags(size: usize, align: usize, flags: DWORD) -> *mut u8 { > if align <= MIN_ALIGN { > HeapAlloc(GetProcessHeap(), flags, size) > } else { > let size = size + align; > let ptr = HeapAlloc(GetProcessHeap(), flags, size); > if ptr.is_null() { > ptr > } else { >@@ -142,26 +141,21 @@ mod platform { > pub unsafe fn alloc(size: usize, align: usize) -> *mut u8 { > allocate_with_flags(size, align, 0) > } > > #[inline] > pub unsafe fn dealloc(ptr: *mut u8, align: usize) { > if align <= MIN_ALIGN { > let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID); >- debug_assert!(err != 0, "Failed to free heap memory: {}", >- GetLastError()); >+ debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); > } else { > let header = get_header(ptr); > let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID); >- debug_assert!(err != 0, "Failed to free heap memory: {}", >- GetLastError()); >+ debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError()); > } > } > > #[inline] > pub unsafe fn realloc(ptr: *mut u8, new_size: usize) -> *mut u8 { >- HeapReAlloc(GetProcessHeap(), >- 0, >- ptr as LPVOID, >- new_size) as *mut u8 >+ HeapReAlloc(GetProcessHeap(), 0, ptr as LPVOID, new_size) as *mut u8 > } > } >diff --git a/servo/components/hashglobe/src/fake.rs b/servo/components/hashglobe/src/fake.rs >index eba21e041488..d2cdd549e48d 100644 >--- a/servo/components/hashglobe/src/fake.rs >+++ b/servo/components/hashglobe/src/fake.rs >@@ -15,59 +15,62 @@ > //! it smooth to switch between hashmap impls in a codebase. > > use std::collections::HashMap as StdMap; > use std::collections::HashSet as StdSet; > use std::fmt; > use std::hash::{BuildHasher, Hash}; > use std::ops::{Deref, DerefMut}; > >-pub use std::collections::hash_map::{Entry, RandomState, Iter as MapIter, IterMut as MapIterMut}; >-pub use std::collections::hash_set::{Iter as SetIter, IntoIter as SetIntoIter}; >+pub use std::collections::hash_map::{Entry, Iter as MapIter, IterMut as MapIterMut, RandomState}; >+pub use std::collections::hash_set::{IntoIter as SetIntoIter, Iter as SetIter}; > > #[derive(Clone)] > pub struct HashMap<K, V, S = RandomState>(StdMap<K, V, S>); > >- > use FailedAllocationError; > > impl<K, V, S> Deref for HashMap<K, V, S> { > type Target = StdMap<K, V, S>; > fn deref(&self) -> &Self::Target { > &self.0 > } > } > > impl<K, V, S> DerefMut for HashMap<K, V, S> { > fn deref_mut(&mut self) -> &mut Self::Target { > &mut self.0 > } > } > > impl<K, V, S> HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > #[inline] > pub fn try_with_hasher(hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> { > Ok(HashMap(StdMap::with_hasher(hash_builder))) > } > > #[inline] >- pub fn try_with_capacity_and_hasher(capacity: usize, >- hash_builder: S) >- -> Result<HashMap<K, V, S>, FailedAllocationError> { >- Ok(HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder))) >+ pub fn try_with_capacity_and_hasher( >+ capacity: usize, >+ hash_builder: S, >+ ) -> Result<HashMap<K, V, S>, FailedAllocationError> { >+ Ok(HashMap(StdMap::with_capacity_and_hasher( >+ capacity, >+ hash_builder, >+ ))) > } > > pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> HashMap<K, V, S> { > HashMap(StdMap::with_capacity_and_hasher(capacity, hash_builder)) > } > >- > #[inline] > pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> { > Ok(self.reserve(additional)) > } > > pub fn try_shrink_to_fit(&mut self) -> Result<(), FailedAllocationError> { > Ok(self.shrink_to_fit()) > } >@@ -80,17 +83,16 @@ impl<K, V, S> HashMap<K, V, S> > pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, FailedAllocationError> { > Ok(self.insert(k, v)) > } > } > > #[derive(Clone)] > pub struct HashSet<T, S = RandomState>(StdSet<T, S>); > >- > impl<T, S> Deref for HashSet<T, S> { > type Target = StdSet<T, S>; > fn deref(&self) -> &Self::Target { > &self.0 > } > } > > impl<T, S> DerefMut for HashSet<T, S> { >@@ -106,27 +108,26 @@ impl<T: Hash + Eq> HashSet<T, RandomState> { > } > > #[inline] > pub fn with_capacity(capacity: usize) -> HashSet<T, RandomState> { > HashSet(StdSet::with_capacity(capacity)) > } > } > >- > impl<T, S> HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > #[inline] > pub fn with_hasher(hasher: S) -> HashSet<T, S> { > HashSet(StdSet::with_hasher(hasher)) > } > >- > #[inline] > pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> { > HashSet(StdSet::with_capacity_and_hasher(capacity, hasher)) > } > > #[inline] > pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> { > Ok(self.reserve(additional)) >@@ -148,113 +149,121 @@ impl<T, S> HashSet<T, S> > > impl<K: Hash + Eq, V, S: BuildHasher + Default> Default for HashMap<K, V, S> { > fn default() -> Self { > HashMap(Default::default()) > } > } > > impl<K, V, S> fmt::Debug for HashMap<K, V, S> >- where K: Eq + Hash + fmt::Debug, >- V: fmt::Debug, >- S: BuildHasher { >+where >+ K: Eq + Hash + fmt::Debug, >+ V: fmt::Debug, >+ S: BuildHasher, >+{ > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > self.0.fmt(f) > } > } > > impl<K, V, S> PartialEq for HashMap<K, V, S> >- where K: Eq + Hash, >- V: PartialEq, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ V: PartialEq, >+ S: BuildHasher, > { > fn eq(&self, other: &HashMap<K, V, S>) -> bool { > self.0.eq(&other.0) > } > } > > impl<K, V, S> Eq for HashMap<K, V, S> >- where K: Eq + Hash, >- V: Eq, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ V: Eq, >+ S: BuildHasher, > { > } > > impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > type Item = (&'a K, &'a V); > type IntoIter = MapIter<'a, K, V>; > > fn into_iter(self) -> MapIter<'a, K, V> { > self.0.iter() > } > } > > impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > type Item = (&'a K, &'a mut V); > type IntoIter = MapIterMut<'a, K, V>; > > fn into_iter(self) -> MapIterMut<'a, K, V> { > self.0.iter_mut() > } > } > > impl<T: Eq + Hash, S: BuildHasher + Default> Default for HashSet<T, S> { > fn default() -> Self { > HashSet(Default::default()) > } > } > > impl<T, S> fmt::Debug for HashSet<T, S> >- where T: Eq + Hash + fmt::Debug, >- S: BuildHasher >+where >+ T: Eq + Hash + fmt::Debug, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > self.0.fmt(f) > } > } > > impl<T, S> PartialEq for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn eq(&self, other: &HashSet<T, S>) -> bool { > self.0.eq(&other.0) > } > } > > impl<T, S> Eq for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > } > > impl<'a, T, S> IntoIterator for &'a HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > type IntoIter = SetIter<'a, T>; > > fn into_iter(self) -> SetIter<'a, T> { > self.0.iter() > } > } > > impl<T, S> IntoIterator for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = T; > type IntoIter = SetIntoIter<T>; > >- > fn into_iter(self) -> SetIntoIter<T> { > self.0.into_iter() > } > } >- >- >diff --git a/servo/components/hashglobe/src/hash_map.rs b/servo/components/hashglobe/src/hash_map.rs >index 27077526b3ae..0946ed636903 100644 >--- a/servo/components/hashglobe/src/hash_map.rs >+++ b/servo/components/hashglobe/src/hash_map.rs >@@ -10,27 +10,27 @@ > > use self::Entry::*; > use self::VacantEntryState::*; > > use std::borrow::Borrow; > use std::cmp::max; > use std::fmt::{self, Debug}; > #[allow(deprecated)] >-use std::hash::{Hash, BuildHasher}; >+use std::hash::{BuildHasher, Hash}; > use std::iter::FromIterator; > use std::mem::{self, replace}; > use std::ops::{Deref, Index}; > >-use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash}; > use super::table::BucketState::{Empty, Full}; >+use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash}; > > use FailedAllocationError; > >-const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two >+const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two > > /// The default behavior of HashMap implements a maximum load factor of 90.9%. > #[derive(Clone)] > struct DefaultResizePolicy; > > impl DefaultResizePolicy { > fn new() -> DefaultResizePolicy { > DefaultResizePolicy >@@ -45,17 +45,19 @@ impl DefaultResizePolicy { > if len == 0 { > 0 > } else { > // 1. Account for loading: `raw_capacity >= len * 1.1`. > // 2. Ensure it is a power of two. > // 3. Ensure it is at least the minimum size. > let mut raw_cap = len * 11 / 10; > assert!(raw_cap >= len, "raw_cap overflow"); >- raw_cap = raw_cap.checked_next_power_of_two().expect("raw_capacity overflow"); >+ raw_cap = raw_cap >+ .checked_next_power_of_two() >+ .expect("raw_capacity overflow"); > raw_cap = max(MIN_NONZERO_RAW_CAPACITY, raw_cap); > raw_cap > } > } > > /// The capacity of the given raw capacity. > #[inline] > fn capacity(&self, raw_cap: usize) -> usize { >@@ -393,18 +395,19 @@ pub struct HashMap<K, V, S = RandomState> { > table: RawTable<K, V>, > > resize_policy: DefaultResizePolicy, > } > > /// Search for a pre-hashed key. > #[inline] > fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> InternalEntry<K, V, M> >- where M: Deref<Target = RawTable<K, V>>, >- F: FnMut(&K) -> bool >+where >+ M: Deref<Target = RawTable<K, V>>, >+ F: FnMut(&K) -> bool, > { > // This is the only function where capacity can be zero. To avoid > // undefined behavior when Bucket::new gets the raw bucket in this > // case, immediately return the appropriate search result. > if table.capacity() == 0 { > return InternalEntry::TableIsEmpty; > } > >@@ -444,48 +447,47 @@ fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> Inter > } > } > displacement += 1; > probe = full.next(); > debug_assert!(displacement <= size); > } > } > >-fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) >- -> (K, V, &mut RawTable<K, V>) >-{ >+fn pop_internal<K, V>(starting_bucket: FullBucketMut<K, V>) -> (K, V, &mut RawTable<K, V>) { > let (empty, retkey, retval) = starting_bucket.take(); > let mut gap = match empty.gap_peek() { > Ok(b) => b, > Err(b) => return (retkey, retval, b.into_table()), > }; > > while gap.full().displacement() != 0 { > gap = match gap.shift() { > Ok(b) => b, > Err(b) => { > return (retkey, retval, b.into_table()); >- }, >+ } > }; > } > > // Now we've done all our shifting. Return the value we grabbed earlier. > (retkey, retval, gap.into_table()) > } > > /// Perform robin hood bucket stealing at the given `bucket`. You must > /// also pass that bucket's displacement so we don't have to recalculate it. > /// > /// `hash`, `key`, and `val` are the elements to "robin hood" into the hashtable. >-fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>, >- mut displacement: usize, >- mut hash: SafeHash, >- mut key: K, >- mut val: V) >- -> FullBucketMut<'a, K, V> { >+fn robin_hood<'a, K: 'a, V: 'a>( >+ bucket: FullBucketMut<'a, K, V>, >+ mut displacement: usize, >+ mut hash: SafeHash, >+ mut key: K, >+ mut val: V, >+) -> FullBucketMut<'a, K, V> { > let size = bucket.table().size(); > let raw_capacity = bucket.table().capacity(); > // There can be at most `size - dib` buckets to displace, because > // in the worst case, there are `size` elements and we already are > // `displacement` buckets away from the initial one. > let idx_end = (bucket.index() + size - bucket.displacement()) % raw_capacity; > // Save the *starting point*. > let mut bucket = bucket.stash(); >@@ -526,41 +528,45 @@ fn robin_hood<'a, K: 'a, V: 'a>(bucket: FullBucketMut<'a, K, V>, > displacement = probe_displacement; > break; > } > } > } > } > > impl<K, V, S> HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > fn make_hash<X: ?Sized>(&self, x: &X) -> SafeHash >- where X: Hash >+ where >+ X: Hash, > { > table::make_hash(&self.hash_builder, x) > } > > /// Search for a key, yielding the index if it's found in the hashtable. > /// If you already have the hash for the key lying around, use > /// search_hashed. > #[inline] > fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> InternalEntry<K, V, &'a RawTable<K, V>> >- where K: Borrow<Q>, >- Q: Eq + Hash >+ where >+ K: Borrow<Q>, >+ Q: Eq + Hash, > { > let hash = self.make_hash(q); > search_hashed(&self.table, hash, |k| q.eq(k.borrow())) > } > > #[inline] > fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> InternalEntry<K, V, &'a mut RawTable<K, V>> >- where K: Borrow<Q>, >- Q: Eq + Hash >+ where >+ K: Borrow<Q>, >+ Q: Eq + Hash, > { > let hash = self.make_hash(q); > search_hashed(&mut self.table, hash, |k| q.eq(k.borrow())) > } > > // The caller should ensure that invariants by Robin Hood Hashing hold > // and that there's space in the underlying table. > fn insert_hashed_ordered(&mut self, hash: SafeHash, k: K, v: V) { >@@ -579,18 +585,19 @@ impl<K, V, S> HashMap<K, V, S> > }; > buckets.next(); > debug_assert_ne!(buckets.index(), start_index); > } > } > } > > impl<K, V, S> HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > /// Creates an empty `HashMap` which will use the given hash builder to hash > /// keys. > /// > /// The created map has the default initial capacity. > /// > /// Warning: `hash_builder` is normally randomly generated, and > /// is designed to allow HashMaps to be resistant to attacks that >@@ -638,17 +645,20 @@ impl<K, V, S> HashMap<K, V, S> > /// use std::collections::HashMap; > /// use std::collections::hash_map::RandomState; > /// > /// let s = RandomState::new(); > /// let mut map = HashMap::with_capacity_and_hasher(10, s); > /// map.insert(1, 2); > /// ``` > #[inline] >- pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, FailedAllocationError> { >+ pub fn try_with_capacity_and_hasher( >+ capacity: usize, >+ hash_builder: S, >+ ) -> Result<HashMap<K, V, S>, FailedAllocationError> { > let resize_policy = DefaultResizePolicy::new(); > let raw_cap = resize_policy.raw_capacity(capacity); > Ok(HashMap { > hash_builder, > resize_policy, > table: RawTable::new(raw_cap)?, > }) > } >@@ -703,22 +713,24 @@ impl<K, V, S> HashMap<K, V, S> > /// use std::collections::HashMap; > /// let mut map: HashMap<&str, isize> = HashMap::new(); > /// map.reserve(10); > /// ``` > pub fn reserve(&mut self, additional: usize) { > self.try_reserve(additional).unwrap(); > } > >- > #[inline] > pub fn try_reserve(&mut self, additional: usize) -> Result<(), FailedAllocationError> { > let remaining = self.capacity() - self.len(); // this can't overflow > if remaining < additional { >- let min_cap = self.len().checked_add(additional).expect("reserve overflow"); >+ let min_cap = self >+ .len() >+ .checked_add(additional) >+ .expect("reserve overflow"); > let raw_cap = self.resize_policy.raw_capacity(min_cap); > self.try_resize(raw_cap)?; > } else if self.table.tag() && remaining <= self.len() { > // Probe sequence is too long and table is half full, > // resize early to reduce probing length. > let new_capacity = self.table.capacity() * 2; > self.try_resize(new_capacity)?; > } >@@ -887,17 +899,19 @@ impl<K, V, S> HashMap<K, V, S> > /// *val = *val + 10; > /// } > /// > /// for val in map.values() { > /// println!("{}", val); > /// } > /// ``` > pub fn values_mut(&mut self) -> ValuesMut<K, V> { >- ValuesMut { inner: self.iter_mut() } >+ ValuesMut { >+ inner: self.iter_mut(), >+ } > } > > /// An iterator visiting all key-value pairs in arbitrary order. > /// The iterator element type is `(&'a K, &'a V)`. > /// > /// # Examples > /// > /// ``` >@@ -908,17 +922,19 @@ impl<K, V, S> HashMap<K, V, S> > /// map.insert("b", 2); > /// map.insert("c", 3); > /// > /// for (key, val) in map.iter() { > /// println!("key: {} val: {}", key, val); > /// } > /// ``` > pub fn iter(&self) -> Iter<K, V> { >- Iter { inner: self.table.iter() } >+ Iter { >+ inner: self.table.iter(), >+ } > } > > /// An iterator visiting all key-value pairs in arbitrary order, > /// with mutable references to the values. > /// The iterator element type is `(&'a K, &'a mut V)`. > /// > /// # Examples > /// >@@ -935,17 +951,19 @@ impl<K, V, S> HashMap<K, V, S> > /// *val *= 2; > /// } > /// > /// for (key, val) in &map { > /// println!("key: {} val: {}", key, val); > /// } > /// ``` > pub fn iter_mut(&mut self) -> IterMut<K, V> { >- IterMut { inner: self.table.iter_mut() } >+ IterMut { >+ inner: self.table.iter_mut(), >+ } > } > > /// Gets the given key's corresponding entry in the map for in-place manipulation. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; >@@ -967,17 +985,18 @@ impl<K, V, S> HashMap<K, V, S> > } > > #[inline(always)] > pub fn try_entry(&mut self, key: K) -> Result<Entry<K, V>, FailedAllocationError> { > // Gotta resize now. > self.try_reserve(1)?; > let hash = self.make_hash(&key); > Ok(search_hashed(&mut self.table, hash, |q| q.eq(&key)) >- .into_entry(key).expect("unreachable")) >+ .into_entry(key) >+ .expect("unreachable")) > } > > /// Returns the number of elements in the map. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; >@@ -1023,35 +1042,45 @@ impl<K, V, S> HashMap<K, V, S> > /// for (k, v) in a.drain().take(1) { > /// assert!(k == 1 || k == 2); > /// assert!(v == "a" || v == "b"); > /// } > /// > /// assert!(a.is_empty()); > /// ``` > #[inline] >- pub fn drain(&mut self) -> Drain<K, V> where K: 'static, V: 'static { >- Drain { inner: self.table.drain() } >+ pub fn drain(&mut self) -> Drain<K, V> >+ where >+ K: 'static, >+ V: 'static, >+ { >+ Drain { >+ inner: self.table.drain(), >+ } > } > > /// Clears the map, removing all key-value pairs. Keeps the allocated memory > /// for reuse. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut a = HashMap::new(); > /// a.insert(1, "a"); > /// a.clear(); > /// assert!(a.is_empty()); > /// ``` > #[inline] >- pub fn clear(&mut self) where K: 'static, V: 'static { >+ pub fn clear(&mut self) >+ where >+ K: 'static, >+ V: 'static, >+ { > self.drain(); > } > > /// Returns a reference to the value corresponding to the key. > /// > /// The key may be any borrowed form of the map's key type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for > /// the key type. >@@ -1065,20 +1094,23 @@ impl<K, V, S> HashMap<K, V, S> > /// use std::collections::HashMap; > /// > /// let mut map = HashMap::new(); > /// map.insert(1, "a"); > /// assert_eq!(map.get(&1), Some(&"a")); > /// assert_eq!(map.get(&2), None); > /// ``` > pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V> >- where K: Borrow<Q>, >- Q: Hash + Eq >+ where >+ K: Borrow<Q>, >+ Q: Hash + Eq, > { >- self.search(k).into_occupied_bucket().map(|bucket| bucket.into_refs().1) >+ self.search(k) >+ .into_occupied_bucket() >+ .map(|bucket| bucket.into_refs().1) > } > > /// Returns true if the map contains a value for the specified key. > /// > /// The key may be any borrowed form of the map's key type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for > /// the key type. > /// >@@ -1091,18 +1123,19 @@ impl<K, V, S> HashMap<K, V, S> > /// use std::collections::HashMap; > /// > /// let mut map = HashMap::new(); > /// map.insert(1, "a"); > /// assert_eq!(map.contains_key(&1), true); > /// assert_eq!(map.contains_key(&2), false); > /// ``` > pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool >- where K: Borrow<Q>, >- Q: Hash + Eq >+ where >+ K: Borrow<Q>, >+ Q: Hash + Eq, > { > self.search(k).into_occupied_bucket().is_some() > } > > /// Returns a mutable reference to the value corresponding to the key. > /// > /// The key may be any borrowed form of the map's key type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for >@@ -1119,20 +1152,23 @@ impl<K, V, S> HashMap<K, V, S> > /// let mut map = HashMap::new(); > /// map.insert(1, "a"); > /// if let Some(x) = map.get_mut(&1) { > /// *x = "b"; > /// } > /// assert_eq!(map[&1], "b"); > /// ``` > pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V> >- where K: Borrow<Q>, >- Q: Hash + Eq >+ where >+ K: Borrow<Q>, >+ Q: Hash + Eq, > { >- self.search_mut(k).into_occupied_bucket().map(|bucket| bucket.into_mut_refs().1) >+ self.search_mut(k) >+ .into_occupied_bucket() >+ .map(|bucket| bucket.into_mut_refs().1) > } > > /// Inserts a key-value pair into the map. > /// > /// If the map did not have this key present, [`None`] is returned. > /// > /// If the map did have this key present, the value is updated, and the old > /// value is returned. The key is not updated, though; this matters for >@@ -1182,41 +1218,45 @@ impl<K, V, S> HashMap<K, V, S> > /// use std::collections::HashMap; > /// > /// let mut map = HashMap::new(); > /// map.insert(1, "a"); > /// assert_eq!(map.remove(&1), Some("a")); > /// assert_eq!(map.remove(&1), None); > /// ``` > pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V> >- where K: Borrow<Q>, >- Q: Hash + Eq >+ where >+ K: Borrow<Q>, >+ Q: Hash + Eq, > { > if self.table.size() == 0 { > return None; > } > >- self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1) >+ self.search_mut(k) >+ .into_occupied_bucket() >+ .map(|bucket| pop_internal(bucket).1) > } > > /// Retains only the elements specified by the predicate. > /// > /// In other words, remove all pairs `(k, v)` such that `f(&k,&mut v)` returns `false`. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<isize, isize> = (0..8).map(|x|(x, x*10)).collect(); > /// map.retain(|&k, _| k % 2 == 0); > /// assert_eq!(map.len(), 4); > /// ``` > pub fn retain<F>(&mut self, mut f: F) >- where F: FnMut(&K, &mut V) -> bool >+ where >+ F: FnMut(&K, &mut V) -> bool, > { > if self.table.size() == 0 { > return; > } > let mut elems_left = self.table.size(); > let mut bucket = Bucket::head_bucket(&mut self.table); > bucket.prev(); > let start_index = bucket.index(); >@@ -1230,72 +1270,76 @@ impl<K, V, S> HashMap<K, V, S> > }; > if should_remove { > let prev_raw = full.raw(); > let (_, _, t) = pop_internal(full); > Bucket::new_from(prev_raw, t) > } else { > full.into_bucket() > } >- }, >- Empty(b) => { >- b.into_bucket() > } >+ Empty(b) => b.into_bucket(), > }; >- bucket.prev(); // reverse iteration >+ bucket.prev(); // reverse iteration > debug_assert!(elems_left == 0 || bucket.index() != start_index); > } > } > } > > impl<K, V, S> PartialEq for HashMap<K, V, S> >- where K: Eq + Hash, >- V: PartialEq, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ V: PartialEq, >+ S: BuildHasher, > { > fn eq(&self, other: &HashMap<K, V, S>) -> bool { > if self.len() != other.len() { > return false; > } > >- self.iter().all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) >+ self.iter() >+ .all(|(key, value)| other.get(key).map_or(false, |v| *value == *v)) > } > } > > impl<K, V, S> Eq for HashMap<K, V, S> >- where K: Eq + Hash, >- V: Eq, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ V: Eq, >+ S: BuildHasher, > { > } > > impl<K, V, S> Debug for HashMap<K, V, S> >- where K: Eq + Hash + Debug, >- V: Debug, >- S: BuildHasher >+where >+ K: Eq + Hash + Debug, >+ V: Debug, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_map().entries(self.iter()).finish() > } > } > > impl<K, V, S> Default for HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher + Default >+where >+ K: Eq + Hash, >+ S: BuildHasher + Default, > { > /// Creates an empty `HashMap<K, V, S>`, with the `Default` value for the hasher. > fn default() -> HashMap<K, V, S> { > HashMap::with_hasher(Default::default()) > } > } > > impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S> >- where K: Eq + Hash + Borrow<Q>, >- Q: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash + Borrow<Q>, >+ Q: Eq + Hash, >+ S: BuildHasher, > { > type Output = V; > > #[inline] > fn index(&self, index: &Q) -> &V { > self.get(index).expect("no entry found for key") > } > } >@@ -1309,25 +1353,25 @@ impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S> > /// [`HashMap`]: struct.HashMap.html > pub struct Iter<'a, K: 'a, V: 'a> { > inner: table::Iter<'a, K, V>, > } > > // FIXME(#19839) Remove in favor of `#[derive(Clone)]` > impl<'a, K, V> Clone for Iter<'a, K, V> { > fn clone(&self) -> Iter<'a, K, V> { >- Iter { inner: self.inner.clone() } >+ Iter { >+ inner: self.inner.clone(), >+ } > } > } > > impl<'a, K: Debug, V: Debug> fmt::Debug for Iter<'a, K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.clone()) >- .finish() >+ f.debug_list().entries(self.clone()).finish() > } > } > > /// A mutable iterator over the entries of a `HashMap`. > /// > /// This `struct` is created by the [`iter_mut`] method on [`HashMap`]. See its > /// documentation for more. > /// >@@ -1357,25 +1401,25 @@ pub struct IntoIter<K, V> { > /// [`HashMap`]: struct.HashMap.html > pub struct Keys<'a, K: 'a, V: 'a> { > inner: Iter<'a, K, V>, > } > > // FIXME(#19839) Remove in favor of `#[derive(Clone)]` > impl<'a, K, V> Clone for Keys<'a, K, V> { > fn clone(&self) -> Keys<'a, K, V> { >- Keys { inner: self.inner.clone() } >+ Keys { >+ inner: self.inner.clone(), >+ } > } > } > > impl<'a, K: Debug, V> fmt::Debug for Keys<'a, K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.clone()) >- .finish() >+ f.debug_list().entries(self.clone()).finish() > } > } > > /// An iterator over the values of a `HashMap`. > /// > /// This `struct` is created by the [`values`] method on [`HashMap`]. See its > /// documentation for more. > /// >@@ -1383,25 +1427,25 @@ impl<'a, K: Debug, V> fmt::Debug for Keys<'a, K, V> { > /// [`HashMap`]: struct.HashMap.html > pub struct Values<'a, K: 'a, V: 'a> { > inner: Iter<'a, K, V>, > } > > // FIXME(#19839) Remove in favor of `#[derive(Clone)]` > impl<'a, K, V> Clone for Values<'a, K, V> { > fn clone(&self) -> Values<'a, K, V> { >- Values { inner: self.inner.clone() } >+ Values { >+ inner: self.inner.clone(), >+ } > } > } > > impl<'a, K, V: Debug> fmt::Debug for Values<'a, K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.clone()) >- .finish() >+ f.debug_list().entries(self.clone()).finish() > } > } > > /// A draining iterator over the entries of a `HashMap`. > /// > /// This `struct` is created by the [`drain`] method on [`HashMap`]. See its > /// documentation for more. > /// >@@ -1418,17 +1462,19 @@ pub struct Drain<'a, K: 'static, V: 'static> { > /// > /// [`values_mut`]: struct.HashMap.html#method.values_mut > /// [`HashMap`]: struct.HashMap.html > pub struct ValuesMut<'a, K: 'a, V: 'a> { > inner: IterMut<'a, K, V>, > } > > enum InternalEntry<K, V, M> { >- Occupied { elem: FullBucket<K, V, M> }, >+ Occupied { >+ elem: FullBucket<K, V, M>, >+ }, > Vacant { > hash: SafeHash, > elem: VacantEntryState<K, V, M>, > }, > TableIsEmpty, > } > > impl<K, V, M> InternalEntry<K, V, M> { >@@ -1440,61 +1486,45 @@ impl<K, V, M> InternalEntry<K, V, M> { > } > } > } > > impl<'a, K, V> InternalEntry<K, V, &'a mut RawTable<K, V>> { > #[inline] > fn into_entry(self, key: K) -> Option<Entry<'a, K, V>> { > match self { >- InternalEntry::Occupied { elem } => { >- Some(Occupied(OccupiedEntry { >- key: Some(key), >- elem, >- })) >- } >- InternalEntry::Vacant { hash, elem } => { >- Some(Vacant(VacantEntry { >- hash, >- key, >- elem, >- })) >- } >+ InternalEntry::Occupied { elem } => Some(Occupied(OccupiedEntry { >+ key: Some(key), >+ elem, >+ })), >+ InternalEntry::Vacant { hash, elem } => Some(Vacant(VacantEntry { hash, key, elem })), > InternalEntry::TableIsEmpty => None, > } > } > } > > /// A view into a single entry in a map, which may either be vacant or occupied. > /// > /// This `enum` is constructed from the [`entry`] method on [`HashMap`]. > /// > /// [`HashMap`]: struct.HashMap.html > /// [`entry`]: struct.HashMap.html#method.entry > pub enum Entry<'a, K: 'a, V: 'a> { > /// An occupied entry. >- Occupied( OccupiedEntry<'a, K, V>), >+ Occupied(OccupiedEntry<'a, K, V>), > > /// A vacant entry. >- Vacant( VacantEntry<'a, K, V>), >+ Vacant(VacantEntry<'a, K, V>), > } > > impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for Entry<'a, K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > match *self { >- Vacant(ref v) => { >- f.debug_tuple("Entry") >- .field(v) >- .finish() >- } >- Occupied(ref o) => { >- f.debug_tuple("Entry") >- .field(o) >- .finish() >- } >+ Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), >+ Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), > } > } > } > > /// A view into an occupied entry in a `HashMap`. > /// It is part of the [`Entry`] enum. > /// > /// [`Entry`]: enum.Entry.html >@@ -1519,58 +1549,59 @@ impl<'a, K: 'a + Debug, V: 'a + Debug> Debug for OccupiedEntry<'a, K, V> { > pub struct VacantEntry<'a, K: 'a, V: 'a> { > hash: SafeHash, > key: K, > elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>, > } > > impl<'a, K: 'a + Debug, V: 'a> Debug for VacantEntry<'a, K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_tuple("VacantEntry") >- .field(self.key()) >- .finish() >+ f.debug_tuple("VacantEntry").field(self.key()).finish() > } > } > > /// Possible states of a VacantEntry. > enum VacantEntryState<K, V, M> { > /// The index is occupied, but the key to insert has precedence, > /// and will kick the current one out on insertion. > NeqElem(FullBucket<K, V, M>, usize), > /// The index is genuinely vacant. > NoElem(EmptyBucket<K, V, M>, usize), > } > > impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > type Item = (&'a K, &'a V); > type IntoIter = Iter<'a, K, V>; > > fn into_iter(self) -> Iter<'a, K, V> { > self.iter() > } > } > > impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > type Item = (&'a K, &'a mut V); > type IntoIter = IterMut<'a, K, V>; > > fn into_iter(self) -> IterMut<'a, K, V> { > self.iter_mut() > } > } > > impl<K, V, S> IntoIterator for HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > type Item = (K, V); > type IntoIter = IntoIter<K, V>; > > /// Creates a consuming iterator, that is, one that moves each key-value > /// pair out of the map in arbitrary order. The map cannot be used after > /// calling this. > /// >@@ -1583,17 +1614,19 @@ impl<K, V, S> IntoIterator for HashMap<K, V, S> > /// map.insert("a", 1); > /// map.insert("b", 2); > /// map.insert("c", 3); > /// > /// // Not possible with .iter() > /// let vec: Vec<(&str, isize)> = map.into_iter().collect(); > /// ``` > fn into_iter(self) -> IntoIter<K, V> { >- IntoIter { inner: self.table.into_iter() } >+ IntoIter { >+ inner: self.table.into_iter(), >+ } > } > } > > impl<'a, K, V> Iterator for Iter<'a, K, V> { > type Item = (&'a K, &'a V); > > #[inline] > fn next(&mut self) -> Option<(&'a K, &'a V)> { >@@ -1606,17 +1639,16 @@ impl<'a, K, V> Iterator for Iter<'a, K, V> { > } > impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> { > #[inline] > fn len(&self) -> usize { > self.inner.len() > } > } > >- > impl<'a, K, V> Iterator for IterMut<'a, K, V> { > type Item = (&'a K, &'a mut V); > > #[inline] > fn next(&mut self) -> Option<(&'a K, &'a mut V)> { > self.inner.next() > } > #[inline] >@@ -1627,23 +1659,22 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { > impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> { > #[inline] > fn len(&self) -> usize { > self.inner.len() > } > } > > impl<'a, K, V> fmt::Debug for IterMut<'a, K, V> >- where K: fmt::Debug, >- V: fmt::Debug, >+where >+ K: fmt::Debug, >+ V: fmt::Debug, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.inner.iter()) >- .finish() >+ f.debug_list().entries(self.inner.iter()).finish() > } > } > > impl<K, V> Iterator for IntoIter<K, V> { > type Item = (K, V); > > #[inline] > fn next(&mut self) -> Option<(K, V)> { >@@ -1658,19 +1689,17 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> { > #[inline] > fn len(&self) -> usize { > self.inner.len() > } > } > > impl<K: Debug, V: Debug> fmt::Debug for IntoIter<K, V> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.inner.iter()) >- .finish() >+ f.debug_list().entries(self.inner.iter()).finish() > } > } > > impl<'a, K, V> Iterator for Keys<'a, K, V> { > type Item = &'a K; > > #[inline] > fn next(&mut self) -> Option<(&'a K)> { >@@ -1721,23 +1750,22 @@ impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { > impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> { > #[inline] > fn len(&self) -> usize { > self.inner.len() > } > } > > impl<'a, K, V> fmt::Debug for ValuesMut<'a, K, V> >- where K: fmt::Debug, >- V: fmt::Debug, >+where >+ K: fmt::Debug, >+ V: fmt::Debug, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.inner.inner.iter()) >- .finish() >+ f.debug_list().entries(self.inner.inner.iter()).finish() > } > } > > impl<'a, K, V> Iterator for Drain<'a, K, V> { > type Item = (K, V); > > #[inline] > fn next(&mut self) -> Option<(K, V)> { >@@ -1751,30 +1779,29 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> { > impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> { > #[inline] > fn len(&self) -> usize { > self.inner.len() > } > } > > impl<'a, K, V> fmt::Debug for Drain<'a, K, V> >- where K: fmt::Debug, >- V: fmt::Debug, >+where >+ K: fmt::Debug, >+ V: fmt::Debug, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- f.debug_list() >- .entries(self.inner.iter()) >- .finish() >+ f.debug_list().entries(self.inner.iter()).finish() > } > } > > // FORK NOTE: Removed Placer impl > > impl<'a, K, V> Entry<'a, K, V> { >- /// Ensures a value is in the entry by inserting the default if empty, and returns >+ /// Ensures a value is in the entry by inserting the default if empty, and returns > /// a mutable reference to the value in the entry. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); >@@ -1787,17 +1814,17 @@ impl<'a, K, V> Entry<'a, K, V> { > /// ``` > pub fn or_insert(self, default: V) -> &'a mut V { > match self { > Occupied(entry) => entry.into_mut(), > Vacant(entry) => entry.insert(default), > } > } > >- /// Ensures a value is in the entry by inserting the result of the default function if empty, >+ /// Ensures a value is in the entry by inserting the result of the default function if empty, > /// and returns a mutable reference to the value in the entry. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<&str, String> = HashMap::new(); >@@ -1819,17 +1846,17 @@ impl<'a, K, V> Entry<'a, K, V> { > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); > /// ``` >- pub fn key(&self) -> &K { >+ pub fn key(&self) -> &K { > match *self { > Occupied(ref entry) => entry.key(), > Vacant(ref entry) => entry.key(), > } > } > } > > impl<'a, K, V> OccupiedEntry<'a, K, V> { >@@ -1839,17 +1866,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// map.entry("poneyland").or_insert(12); > /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); > /// ``` >- pub fn key(&self) -> &K { >+ pub fn key(&self) -> &K { > self.elem.read().0 > } > > /// Take the ownership of the key and value from the map. > /// > /// # Examples > /// > /// ``` >@@ -1861,17 +1888,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// > /// if let Entry::Occupied(o) = map.entry("poneyland") { > /// // We delete the entry from the map. > /// o.remove_entry(); > /// } > /// > /// assert_eq!(map.contains_key("poneyland"), false); > /// ``` >- pub fn remove_entry(self) -> (K, V) { >+ pub fn remove_entry(self) -> (K, V) { > let (k, v, _) = pop_internal(self.elem); > (k, v) > } > > /// Gets a reference to the value in the entry. > /// > /// # Examples > /// >@@ -1881,17 +1908,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// map.entry("poneyland").or_insert(12); > /// > /// if let Entry::Occupied(o) = map.entry("poneyland") { > /// assert_eq!(o.get(), &12); > /// } > /// ``` >- pub fn get(&self) -> &V { >+ pub fn get(&self) -> &V { > self.elem.read().1 > } > > /// Gets a mutable reference to the value in the entry. > /// > /// # Examples > /// > /// ``` >@@ -1903,17 +1930,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// > /// assert_eq!(map["poneyland"], 12); > /// if let Entry::Occupied(mut o) = map.entry("poneyland") { > /// *o.get_mut() += 10; > /// } > /// > /// assert_eq!(map["poneyland"], 22); > /// ``` >- pub fn get_mut(&mut self) -> &mut V { >+ pub fn get_mut(&mut self) -> &mut V { > self.elem.read_mut().1 > } > > /// Converts the OccupiedEntry into a mutable reference to the value in the entry > /// with a lifetime bound to the map itself. > /// > /// # Examples > /// >@@ -1926,17 +1953,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// > /// assert_eq!(map["poneyland"], 12); > /// if let Entry::Occupied(o) = map.entry("poneyland") { > /// *o.into_mut() += 10; > /// } > /// > /// assert_eq!(map["poneyland"], 22); > /// ``` >- pub fn into_mut(self) -> &'a mut V { >+ pub fn into_mut(self) -> &'a mut V { > self.elem.into_mut_refs().1 > } > > /// Sets the value of the entry, and returns the entry's old value. > /// > /// # Examples > /// > /// ``` >@@ -1947,17 +1974,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// map.entry("poneyland").or_insert(12); > /// > /// if let Entry::Occupied(mut o) = map.entry("poneyland") { > /// assert_eq!(o.insert(15), 12); > /// } > /// > /// assert_eq!(map["poneyland"], 15); > /// ``` >- pub fn insert(&mut self, mut value: V) -> V { >+ pub fn insert(&mut self, mut value: V) -> V { > let old_value = self.get_mut(); > mem::swap(&mut value, old_value); > value > } > > /// Takes the value out of the entry, and returns it. > /// > /// # Examples >@@ -1970,17 +1997,17 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> { > /// map.entry("poneyland").or_insert(12); > /// > /// if let Entry::Occupied(o) = map.entry("poneyland") { > /// assert_eq!(o.remove(), 12); > /// } > /// > /// assert_eq!(map.contains_key("poneyland"), false); > /// ``` >- pub fn remove(self) -> V { >+ pub fn remove(self) -> V { > pop_internal(self.elem).1 > } > > /// Returns a key that was used for search. > /// > /// The key was retained for further use. > fn take_key(&mut self) -> Option<K> { > self.key.take() >@@ -1994,17 +2021,17 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { > /// # Examples > /// > /// ``` > /// use std::collections::HashMap; > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// assert_eq!(map.entry("poneyland").key(), &"poneyland"); > /// ``` >- pub fn key(&self) -> &K { >+ pub fn key(&self) -> &K { > &self.key > } > > /// Take ownership of the key. > /// > /// # Examples > /// > /// ``` >@@ -2012,17 +2039,17 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { > /// use std::collections::hash_map::Entry; > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// > /// if let Entry::Vacant(v) = map.entry("poneyland") { > /// v.into_key(); > /// } > /// ``` >- pub fn into_key(self) -> K { >+ pub fn into_key(self) -> K { > self.key > } > > /// Sets the value of the entry with the VacantEntry's key, > /// and returns a mutable reference to it. > /// > /// # Examples > /// >@@ -2032,49 +2059,51 @@ impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> { > /// > /// let mut map: HashMap<&str, u32> = HashMap::new(); > /// > /// if let Entry::Vacant(o) = map.entry("poneyland") { > /// o.insert(37); > /// } > /// assert_eq!(map["poneyland"], 37); > /// ``` >- pub fn insert(self, value: V) -> &'a mut V { >+ pub fn insert(self, value: V) -> &'a mut V { > let b = match self.elem { > NeqElem(mut bucket, disp) => { > if disp >= DISPLACEMENT_THRESHOLD { > bucket.table_mut().set_tag(true); > } > robin_hood(bucket, disp, self.hash, self.key, value) >- }, >+ } > NoElem(mut bucket, disp) => { > if disp >= DISPLACEMENT_THRESHOLD { > bucket.table_mut().set_tag(true); > } > bucket.put(self.hash, self.key, value) >- }, >+ } > }; > b.into_mut_refs().1 > } > } > > impl<K, V, S> FromIterator<(K, V)> for HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher + Default >+where >+ K: Eq + Hash, >+ S: BuildHasher + Default, > { > fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> HashMap<K, V, S> { > let mut map = HashMap::with_hasher(Default::default()); > map.extend(iter); > map > } > } > > impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) { > // Keys may be already present or show multiple times in the iterator. > // Reserve the entire hint lower bound if the map is empty. > // Otherwise reserve half the hint (rounded up), so the map > // will only resize twice in the worst case. > let iter = iter.into_iter(); > let reserve = if self.is_empty() { >@@ -2085,46 +2114,51 @@ impl<K, V, S> Extend<(K, V)> for HashMap<K, V, S> > self.reserve(reserve); > for (k, v) in iter { > self.insert(k, v); > } > } > } > > impl<'a, K, V, S> Extend<(&'a K, &'a V)> for HashMap<K, V, S> >- where K: Eq + Hash + Copy, >- V: Copy, >- S: BuildHasher >+where >+ K: Eq + Hash + Copy, >+ V: Copy, >+ S: BuildHasher, > { > fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) { > self.extend(iter.into_iter().map(|(&key, &value)| (key, value))); > } > } > > // FORK NOTE: These can be reused > pub use std::collections::hash_map::{DefaultHasher, RandomState}; > >- > impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S> >- where K: Eq + Hash + Borrow<Q>, >- S: BuildHasher, >- Q: Eq + Hash >+where >+ K: Eq + Hash + Borrow<Q>, >+ S: BuildHasher, >+ Q: Eq + Hash, > { > type Key = K; > > fn get(&self, key: &Q) -> Option<&K> { >- self.search(key).into_occupied_bucket().map(|bucket| bucket.into_refs().0) >+ self.search(key) >+ .into_occupied_bucket() >+ .map(|bucket| bucket.into_refs().0) > } > > fn take(&mut self, key: &Q) -> Option<K> { > if self.table.size() == 0 { > return None; > } > >- self.search_mut(key).into_occupied_bucket().map(|bucket| pop_internal(bucket).0) >+ self.search_mut(key) >+ .into_occupied_bucket() >+ .map(|bucket| pop_internal(bucket).0) > } > > fn replace(&mut self, key: K) -> Option<K> { > self.reserve(1); > > match self.entry(key) { > Occupied(mut occupied) => { > let key = occupied.take_key().unwrap(); >@@ -2165,30 +2199,31 @@ fn assert_covariance() { > v > } > fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> { > v > } > fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { > v > } >- fn drain<'new>(d: Drain<'static, &'static str, &'static str>) >- -> Drain<'new, &'new str, &'new str> { >+ fn drain<'new>( >+ d: Drain<'static, &'static str, &'static str>, >+ ) -> Drain<'new, &'new str, &'new str> { > d > } > } > > #[cfg(test)] > mod test_map { > extern crate rand; >- use super::HashMap; >+ use self::rand::{thread_rng, Rng}; > use super::Entry::{Occupied, Vacant}; >+ use super::HashMap; > use super::RandomState; > use cell::RefCell; >- use self::rand::{thread_rng, Rng}; > > #[test] > fn test_zero_capacities() { > type HM = HashMap<i32, i32>; > > let m = HM::new(); > assert_eq!(m.capacity(), 0); > >@@ -2314,29 +2349,29 @@ mod test_map { > for i in 0..50 { > let k = Dropable::new(i); > let v = m.remove(&k); > > assert!(v.is_some()); > > DROP_VECTOR.with(|v| { > assert_eq!(v.borrow()[i], 1); >- assert_eq!(v.borrow()[i+100], 1); >+ assert_eq!(v.borrow()[i + 100], 1); > }); > } > > DROP_VECTOR.with(|v| { > for i in 0..50 { > assert_eq!(v.borrow()[i], 0); >- assert_eq!(v.borrow()[i+100], 0); >+ assert_eq!(v.borrow()[i + 100], 0); > } > > for i in 50..100 { > assert_eq!(v.borrow()[i], 1); >- assert_eq!(v.borrow()[i+100], 1); >+ assert_eq!(v.borrow()[i + 100], 1); > } > }); > } > > DROP_VECTOR.with(|v| { > for i in 0..200 { > assert_eq!(v.borrow()[i], 0); > } >@@ -2383,23 +2418,19 @@ mod test_map { > for i in 0..200 { > assert_eq!(v.borrow()[i], 1); > } > }); > > for _ in half.by_ref() {} > > DROP_VECTOR.with(|v| { >- let nk = (0..100) >- .filter(|&i| v.borrow()[i] == 1) >- .count(); >+ let nk = (0..100).filter(|&i| v.borrow()[i] == 1).count(); > >- let nv = (0..100) >- .filter(|&i| v.borrow()[i + 100] == 1) >- .count(); >+ let nv = (0..100).filter(|&i| v.borrow()[i + 100] == 1).count(); > > assert_eq!(nk, 50); > assert_eq!(nv, 50); > }); > }; > > DROP_VECTOR.with(|v| { > for i in 0..200 { >@@ -2569,17 +2600,17 @@ mod test_map { > assert_eq!(m.remove(&1), Some(2)); > assert_eq!(m.remove(&1), None); > } > > #[test] > fn test_iterate() { > let mut m = HashMap::with_capacity(4); > for i in 0..32 { >- assert!(m.insert(i, i*2).is_none()); >+ assert!(m.insert(i, i * 2).is_none()); > } > assert_eq!(m.len(), 32); > > let mut observed: u32 = 0; > > for (k, v) in &m { > assert_eq!(*v, *k * 2); > observed |= 1 << *k; >@@ -2657,18 +2688,17 @@ mod test_map { > let mut map = HashMap::new(); > let empty: HashMap<i32, i32> = HashMap::new(); > > map.insert(1, 2); > map.insert(3, 4); > > let map_str = format!("{:?}", map); > >- assert!(map_str == "{1: 2, 3: 4}" || >- map_str == "{3: 4, 1: 2}"); >+ assert!(map_str == "{1: 2, 3: 4}" || map_str == "{3: 4, 1: 2}"); > assert_eq!(format!("{:?}", empty), "{}"); > } > > #[test] > fn test_expand() { > let mut m = HashMap::new(); > > assert_eq!(m.len(), 0); >@@ -2876,17 +2906,16 @@ mod test_map { > Occupied(mut view) => { > assert_eq!(view.get(), &10); > assert_eq!(view.insert(100), 10); > } > } > assert_eq!(map.get(&1).unwrap(), &100); > assert_eq!(map.len(), 6); > >- > // Existing key (update) > match map.entry(2) { > Vacant(_) => unreachable!(), > Occupied(mut view) => { > let v = view.get_mut(); > let new_v = (*v) * 10; > *v = new_v; > } >@@ -2899,36 +2928,34 @@ mod test_map { > Vacant(_) => unreachable!(), > Occupied(view) => { > assert_eq!(view.remove(), 30); > } > } > assert_eq!(map.get(&3), None); > assert_eq!(map.len(), 5); > >- > // Inexistent key (insert) > match map.entry(10) { > Occupied(_) => unreachable!(), > Vacant(view) => { > assert_eq!(*view.insert(1000), 1000); > } > } > assert_eq!(map.get(&10).unwrap(), &1000); > assert_eq!(map.len(), 6); > } > > #[test] > fn test_entry_take_doesnt_corrupt() { > #![allow(deprecated)] //rand >- // Test for #19292 >+ // Test for #19292 > fn check(m: &HashMap<isize, ()>) { > for k in m.keys() { >- assert!(m.contains_key(k), >- "{} is in keys() but not in the map?", k); >+ assert!(m.contains_key(k), "{} is in keys() but not in the map?", k); > } > } > > let mut m = HashMap::new(); > let mut rng = thread_rng(); > > // Populate the map with some items. > for _ in 0..50 { >@@ -3024,17 +3051,17 @@ mod test_map { > } > } > assert_eq!(a.len(), 1); > assert_eq!(a[key], value); > } > > #[test] > fn test_retain() { >- let mut map: HashMap<isize, isize> = (0..100).map(|x|(x, x*10)).collect(); >+ let mut map: HashMap<isize, isize> = (0..100).map(|x| (x, x * 10)).collect(); > > map.retain(|&k, _| k % 2 == 0); > assert_eq!(map.len(), 50); > assert_eq!(map[&2], 20); > assert_eq!(map[&4], 40); > assert_eq!(map[&6], 60); > } > >diff --git a/servo/components/hashglobe/src/hash_set.rs b/servo/components/hashglobe/src/hash_set.rs >index 2139b58a6012..694e01c46eb8 100644 >--- a/servo/components/hashglobe/src/hash_set.rs >+++ b/servo/components/hashglobe/src/hash_set.rs >@@ -5,22 +5,22 @@ > // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or > // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license > // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your > // option. This file may not be copied, modified, or distributed > // except according to those terms. > > use std::borrow::Borrow; > use std::fmt; >-use std::hash::{Hash, BuildHasher}; >+use std::hash::{BuildHasher, Hash}; > use std::iter::{Chain, FromIterator}; >-use std::ops::{BitOr, BitAnd, BitXor, Sub}; >+use std::ops::{BitAnd, BitOr, BitXor, Sub}; > >-use super::Recover; > use super::hash_map::{self, HashMap, Keys, RandomState}; >+use super::Recover; > > // Future Optimization (FIXME!) > // ============================= > // > // Iteration over zero sized values is a noop. There is no need > // for `bucket.val` in the case of HashSet. I suppose we would need HKT > // to get rid of it properly. > >@@ -117,18 +117,19 @@ use super::hash_map::{self, HashMap, Keys, RandomState}; > /// [`PartialEq`]: ../../std/cmp/trait.PartialEq.html > /// [`RefCell`]: ../../std/cell/struct.RefCell.html > #[derive(Clone)] > pub struct HashSet<T, S = RandomState> { > map: HashMap<T, (), S>, > } > > impl<T, S> HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > /// Creates a new empty hash set which will use the given hasher to hash > /// keys. > /// > /// The hash set is also created with the default initial capacity. > /// > /// Warning: `hasher` is normally randomly generated, and > /// is designed to allow `HashSet`s to be resistant to attacks that >@@ -142,17 +143,19 @@ impl<T, S> HashSet<T, S> > /// use std::collections::hash_map::RandomState; > /// > /// let s = RandomState::new(); > /// let mut set = HashSet::with_hasher(s); > /// set.insert(2); > /// ``` > #[inline] > pub fn with_hasher(hasher: S) -> HashSet<T, S> { >- HashSet { map: HashMap::with_hasher(hasher) } >+ HashSet { >+ map: HashMap::with_hasher(hasher), >+ } > } > > /// Creates an empty `HashSet` with with the specified capacity, using > /// `hasher` to hash the keys. > /// > /// The hash set will be able to hold at least `capacity` elements without > /// reallocating. If `capacity` is 0, the hash set will not allocate. > /// >@@ -168,17 +171,19 @@ impl<T, S> HashSet<T, S> > /// use std::collections::hash_map::RandomState; > /// > /// let s = RandomState::new(); > /// let mut set = HashSet::with_capacity_and_hasher(10, s); > /// set.insert(1); > /// ``` > #[inline] > pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> HashSet<T, S> { >- HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) } >+ HashSet { >+ map: HashMap::with_capacity_and_hasher(capacity, hasher), >+ } > } > > /// Returns a reference to the set's [`BuildHasher`]. > /// > /// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html > /// > /// # Examples > /// >@@ -260,17 +265,19 @@ impl<T, S> HashSet<T, S> > /// set.insert("b"); > /// > /// // Will print in an arbitrary order. > /// for x in set.iter() { > /// println!("{}", x); > /// } > /// ``` > pub fn iter(&self) -> Iter<T> { >- Iter { iter: self.map.keys() } >+ Iter { >+ iter: self.map.keys(), >+ } > } > > /// Visits the values representing the difference, > /// i.e. the values that are in `self` but not in `other`. > /// > /// # Examples > /// > /// ``` >@@ -314,20 +321,23 @@ impl<T, S> HashSet<T, S> > /// } > /// > /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect(); > /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect(); > /// > /// assert_eq!(diff1, diff2); > /// assert_eq!(diff1, [1, 4].iter().collect()); > /// ``` >- pub fn symmetric_difference<'a>(&'a self, >- other: &'a HashSet<T, S>) >- -> SymmetricDifference<'a, T, S> { >- SymmetricDifference { iter: self.difference(other).chain(other.difference(self)) } >+ pub fn symmetric_difference<'a>( >+ &'a self, >+ other: &'a HashSet<T, S>, >+ ) -> SymmetricDifference<'a, T, S> { >+ SymmetricDifference { >+ iter: self.difference(other).chain(other.difference(self)), >+ } > } > > /// Visits the values representing the intersection, > /// i.e. the values that are both in `self` and `other`. > /// > /// # Examples > /// > /// ``` >@@ -364,17 +374,19 @@ impl<T, S> HashSet<T, S> > /// for x in a.union(&b) { > /// println!("{}", x); > /// } > /// > /// let union: HashSet<_> = a.union(&b).collect(); > /// assert_eq!(union, [1, 2, 3, 4].iter().collect()); > /// ``` > pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> { >- Union { iter: self.iter().chain(other.difference(self)) } >+ Union { >+ iter: self.iter().chain(other.difference(self)), >+ } > } > > /// Returns the number of elements in the set. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashSet; >@@ -418,32 +430,37 @@ impl<T, S> HashSet<T, S> > /// for i in set.drain() { > /// println!("{}", i); > /// } > /// > /// assert!(set.is_empty()); > /// ``` > #[inline] > pub fn drain(&mut self) -> Drain<T> { >- Drain { iter: self.map.drain() } >+ Drain { >+ iter: self.map.drain(), >+ } > } > > /// Clears the set, removing all values. > /// > /// # Examples > /// > /// ``` > /// use std::collections::HashSet; > /// > /// let mut v = HashSet::new(); > /// v.insert(1); > /// v.clear(); > /// assert!(v.is_empty()); > /// ``` >- pub fn clear(&mut self) where T: 'static { >+ pub fn clear(&mut self) >+ where >+ T: 'static, >+ { > self.map.clear() > } > > /// Returns `true` if the set contains a value. > /// > /// The value may be any borrowed form of the set's value type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for > /// the value type. >@@ -456,33 +473,35 @@ impl<T, S> HashSet<T, S> > /// let set: HashSet<_> = [1, 2, 3].iter().cloned().collect(); > /// assert_eq!(set.contains(&1), true); > /// assert_eq!(set.contains(&4), false); > /// ``` > /// > /// [`Eq`]: ../../std/cmp/trait.Eq.html > /// [`Hash`]: ../../std/hash/trait.Hash.html > pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool >- where T: Borrow<Q>, >- Q: Hash + Eq >+ where >+ T: Borrow<Q>, >+ Q: Hash + Eq, > { > self.map.contains_key(value) > } > > /// Returns a reference to the value in the set, if any, that is equal to the given value. > /// > /// The value may be any borrowed form of the set's value type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for > /// the value type. > /// > /// [`Eq`]: ../../std/cmp/trait.Eq.html > /// [`Hash`]: ../../std/hash/trait.Hash.html > pub fn get<Q: ?Sized>(&self, value: &Q) -> Option<&T> >- where T: Borrow<Q>, >- Q: Hash + Eq >+ where >+ T: Borrow<Q>, >+ Q: Hash + Eq, > { > Recover::get(&self.map, value) > } > > /// Returns `true` if `self` has no elements in common with `other`. > /// This is equivalent to checking for an empty intersection. > /// > /// # Examples >@@ -593,33 +612,35 @@ impl<T, S> HashSet<T, S> > /// set.insert(2); > /// assert_eq!(set.remove(&2), true); > /// assert_eq!(set.remove(&2), false); > /// ``` > /// > /// [`Eq`]: ../../std/cmp/trait.Eq.html > /// [`Hash`]: ../../std/hash/trait.Hash.html > pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool >- where T: Borrow<Q>, >- Q: Hash + Eq >+ where >+ T: Borrow<Q>, >+ Q: Hash + Eq, > { > self.map.remove(value).is_some() > } > > /// Removes and returns the value in the set, if any, that is equal to the given one. > /// > /// The value may be any borrowed form of the set's value type, but > /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for > /// the value type. > /// > /// [`Eq`]: ../../std/cmp/trait.Eq.html > /// [`Hash`]: ../../std/hash/trait.Hash.html > pub fn take<Q: ?Sized>(&mut self, value: &Q) -> Option<T> >- where T: Borrow<Q>, >- Q: Hash + Eq >+ where >+ T: Borrow<Q>, >+ Q: Hash + Eq, > { > Recover::take(&mut self.map, value) > } > > /// Retains only the elements specified by the predicate. > /// > /// In other words, remove all elements `e` such that `f(&e)` returns `false`. > /// >@@ -629,92 +650,103 @@ impl<T, S> HashSet<T, S> > /// use std::collections::HashSet; > /// > /// let xs = [1,2,3,4,5,6]; > /// let mut set: HashSet<isize> = xs.iter().cloned().collect(); > /// set.retain(|&k| k % 2 == 0); > /// assert_eq!(set.len(), 3); > /// ``` > pub fn retain<F>(&mut self, mut f: F) >- where F: FnMut(&T) -> bool >+ where >+ F: FnMut(&T) -> bool, > { > self.map.retain(|k, _| f(k)); > } > } > > impl<T, S> PartialEq for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn eq(&self, other: &HashSet<T, S>) -> bool { > if self.len() != other.len() { > return false; > } > > self.iter().all(|key| other.contains(key)) > } > } > > impl<T, S> Eq for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > } > > impl<T, S> fmt::Debug for HashSet<T, S> >- where T: Eq + Hash + fmt::Debug, >- S: BuildHasher >+where >+ T: Eq + Hash + fmt::Debug, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_set().entries(self.iter()).finish() > } > } > > impl<T, S> FromIterator<T> for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher + Default >+where >+ T: Eq + Hash, >+ S: BuildHasher + Default, > { > fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> HashSet<T, S> { > let mut set = HashSet::with_hasher(Default::default()); > set.extend(iter); > set > } > } > > impl<T, S> Extend<T> for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) { > self.map.extend(iter.into_iter().map(|k| (k, ()))); > } > } > > impl<'a, T, S> Extend<&'a T> for HashSet<T, S> >- where T: 'a + Eq + Hash + Copy, >- S: BuildHasher >+where >+ T: 'a + Eq + Hash + Copy, >+ S: BuildHasher, > { > fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) { > self.extend(iter.into_iter().cloned()); > } > } > > impl<T, S> Default for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher + Default >+where >+ T: Eq + Hash, >+ S: BuildHasher + Default, > { > /// Creates an empty `HashSet<T, S>` with the `Default` value for the hasher. > fn default() -> HashSet<T, S> { >- HashSet { map: HashMap::default() } >+ HashSet { >+ map: HashMap::default(), >+ } > } > } > > impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S> >- where T: Eq + Hash + Clone, >- S: BuildHasher + Default >+where >+ T: Eq + Hash + Clone, >+ S: BuildHasher + Default, > { > type Output = HashSet<T, S>; > > /// Returns the union of `self` and `rhs` as a new `HashSet<T, S>`. > /// > /// # Examples > /// > /// ``` >@@ -734,18 +766,19 @@ impl<'a, 'b, T, S> BitOr<&'b HashSet<T, S>> for &'a HashSet<T, S> > /// assert_eq!(i, expected.len()); > /// ``` > fn bitor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { > self.union(rhs).cloned().collect() > } > } > > impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S> >- where T: Eq + Hash + Clone, >- S: BuildHasher + Default >+where >+ T: Eq + Hash + Clone, >+ S: BuildHasher + Default, > { > type Output = HashSet<T, S>; > > /// Returns the intersection of `self` and `rhs` as a new `HashSet<T, S>`. > /// > /// # Examples > /// > /// ``` >@@ -765,18 +798,19 @@ impl<'a, 'b, T, S> BitAnd<&'b HashSet<T, S>> for &'a HashSet<T, S> > /// assert_eq!(i, expected.len()); > /// ``` > fn bitand(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { > self.intersection(rhs).cloned().collect() > } > } > > impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S> >- where T: Eq + Hash + Clone, >- S: BuildHasher + Default >+where >+ T: Eq + Hash + Clone, >+ S: BuildHasher + Default, > { > type Output = HashSet<T, S>; > > /// Returns the symmetric difference of `self` and `rhs` as a new `HashSet<T, S>`. > /// > /// # Examples > /// > /// ``` >@@ -796,18 +830,19 @@ impl<'a, 'b, T, S> BitXor<&'b HashSet<T, S>> for &'a HashSet<T, S> > /// assert_eq!(i, expected.len()); > /// ``` > fn bitxor(self, rhs: &HashSet<T, S>) -> HashSet<T, S> { > self.symmetric_difference(rhs).cloned().collect() > } > } > > impl<'a, 'b, T, S> Sub<&'b HashSet<T, S>> for &'a HashSet<T, S> >- where T: Eq + Hash + Clone, >- S: BuildHasher + Default >+where >+ T: Eq + Hash + Clone, >+ S: BuildHasher + Default, > { > type Output = HashSet<T, S>; > > /// Returns the difference of `self` and `rhs` as a new `HashSet<T, S>`. > /// > /// # Examples > /// > /// ``` >@@ -910,30 +945,32 @@ pub struct SymmetricDifference<'a, T: 'a, S: 'a> { > /// > /// [`HashSet`]: struct.HashSet.html > /// [`union`]: struct.HashSet.html#method.union > pub struct Union<'a, T: 'a, S: 'a> { > iter: Chain<Iter<'a, T>, Difference<'a, T, S>>, > } > > impl<'a, T, S> IntoIterator for &'a HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > type IntoIter = Iter<'a, T>; > > fn into_iter(self) -> Iter<'a, T> { > self.iter() > } > } > > impl<T, S> IntoIterator for HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = T; > type IntoIter = IntoIter<T>; > > /// Creates a consuming iterator, that is, one that moves each value out > /// of the set in arbitrary order. The set cannot be used after calling > /// this. > /// >@@ -949,23 +986,27 @@ impl<T, S> IntoIterator for HashSet<T, S> > /// let v: Vec<String> = set.into_iter().collect(); > /// > /// // Will print in an arbitrary order. > /// for x in &v { > /// println!("{}", x); > /// } > /// ``` > fn into_iter(self) -> IntoIter<T> { >- IntoIter { iter: self.map.into_iter() } >+ IntoIter { >+ iter: self.map.into_iter(), >+ } > } > } > > impl<'a, K> Clone for Iter<'a, K> { > fn clone(&self) -> Iter<'a, K> { >- Iter { iter: self.iter.clone() } >+ Iter { >+ iter: self.iter.clone(), >+ } > } > } > impl<'a, K> Iterator for Iter<'a, K> { > type Item = &'a K; > > fn next(&mut self) -> Option<&'a K> { > self.iter.next() > } >@@ -998,20 +1039,17 @@ impl<K> Iterator for IntoIter<K> { > impl<K> ExactSizeIterator for IntoIter<K> { > fn len(&self) -> usize { > self.iter.len() > } > } > > impl<K: fmt::Debug> fmt::Debug for IntoIter<K> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- let entries_iter = self.iter >- .inner >- .iter() >- .map(|(k, _)| k); >+ let entries_iter = self.iter.inner.iter().map(|(k, _)| k); > f.debug_list().entries(entries_iter).finish() > } > } > > impl<'a, K> Iterator for Drain<'a, K> { > type Item = K; > > fn next(&mut self) -> Option<K> { >@@ -1024,33 +1062,34 @@ impl<'a, K> Iterator for Drain<'a, K> { > impl<'a, K> ExactSizeIterator for Drain<'a, K> { > fn len(&self) -> usize { > self.iter.len() > } > } > > impl<'a, K: fmt::Debug> fmt::Debug for Drain<'a, K> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- let entries_iter = self.iter >- .inner >- .iter() >- .map(|(k, _)| k); >+ let entries_iter = self.iter.inner.iter().map(|(k, _)| k); > f.debug_list().entries(entries_iter).finish() > } > } > > impl<'a, T, S> Clone for Intersection<'a, T, S> { > fn clone(&self) -> Intersection<'a, T, S> { >- Intersection { iter: self.iter.clone(), ..*self } >+ Intersection { >+ iter: self.iter.clone(), >+ ..*self >+ } > } > } > > impl<'a, T, S> Iterator for Intersection<'a, T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > > fn next(&mut self) -> Option<&'a T> { > loop { > let elt = self.iter.next()?; > if self.other.contains(elt) { > return Some(elt); >@@ -1060,33 +1099,38 @@ impl<'a, T, S> Iterator for Intersection<'a, T, S> > > fn size_hint(&self) -> (usize, Option<usize>) { > let (_, upper) = self.iter.size_hint(); > (0, upper) > } > } > > impl<'a, T, S> fmt::Debug for Intersection<'a, T, S> >- where T: fmt::Debug + Eq + Hash, >- S: BuildHasher >+where >+ T: fmt::Debug + Eq + Hash, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_list().entries(self.clone()).finish() > } > } > > impl<'a, T, S> Clone for Difference<'a, T, S> { > fn clone(&self) -> Difference<'a, T, S> { >- Difference { iter: self.iter.clone(), ..*self } >+ Difference { >+ iter: self.iter.clone(), >+ ..*self >+ } > } > } > > impl<'a, T, S> Iterator for Difference<'a, T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > > fn next(&mut self) -> Option<&'a T> { > loop { > let elt = self.iter.next()?; > if !self.other.contains(elt) { > return Some(elt); >@@ -1096,71 +1140,80 @@ impl<'a, T, S> Iterator for Difference<'a, T, S> > > fn size_hint(&self) -> (usize, Option<usize>) { > let (_, upper) = self.iter.size_hint(); > (0, upper) > } > } > > impl<'a, T, S> fmt::Debug for Difference<'a, T, S> >- where T: fmt::Debug + Eq + Hash, >- S: BuildHasher >+where >+ T: fmt::Debug + Eq + Hash, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_list().entries(self.clone()).finish() > } > } > > impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> { > fn clone(&self) -> SymmetricDifference<'a, T, S> { >- SymmetricDifference { iter: self.iter.clone() } >+ SymmetricDifference { >+ iter: self.iter.clone(), >+ } > } > } > > impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > > fn next(&mut self) -> Option<&'a T> { > self.iter.next() > } > fn size_hint(&self) -> (usize, Option<usize>) { > self.iter.size_hint() > } > } > > impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S> >- where T: fmt::Debug + Eq + Hash, >- S: BuildHasher >+where >+ T: fmt::Debug + Eq + Hash, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_list().entries(self.clone()).finish() > } > } > > impl<'a, T, S> Clone for Union<'a, T, S> { > fn clone(&self) -> Union<'a, T, S> { >- Union { iter: self.iter.clone() } >+ Union { >+ iter: self.iter.clone(), >+ } > } > } > > impl<'a, T, S> fmt::Debug for Union<'a, T, S> >- where T: fmt::Debug + Eq + Hash, >- S: BuildHasher >+where >+ T: fmt::Debug + Eq + Hash, >+ S: BuildHasher, > { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.debug_list().entries(self.clone()).finish() > } > } > > impl<'a, T, S> Iterator for Union<'a, T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > type Item = &'a T; > > fn next(&mut self) -> Option<&'a T> { > self.iter.next() > } > fn size_hint(&self) -> (usize, Option<usize>) { > self.iter.size_hint() >@@ -1173,41 +1226,45 @@ fn assert_covariance() { > v > } > fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { > v > } > fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { > v > } >- fn difference<'a, 'new>(v: Difference<'a, &'static str, RandomState>) >- -> Difference<'a, &'new str, RandomState> { >+ fn difference<'a, 'new>( >+ v: Difference<'a, &'static str, RandomState>, >+ ) -> Difference<'a, &'new str, RandomState> { > v > } >- fn symmetric_difference<'a, 'new>(v: SymmetricDifference<'a, &'static str, RandomState>) >- -> SymmetricDifference<'a, &'new str, RandomState> { >+ fn symmetric_difference<'a, 'new>( >+ v: SymmetricDifference<'a, &'static str, RandomState>, >+ ) -> SymmetricDifference<'a, &'new str, RandomState> { > v > } >- fn intersection<'a, 'new>(v: Intersection<'a, &'static str, RandomState>) >- -> Intersection<'a, &'new str, RandomState> { >+ fn intersection<'a, 'new>( >+ v: Intersection<'a, &'static str, RandomState>, >+ ) -> Intersection<'a, &'new str, RandomState> { > v > } >- fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>) >- -> Union<'a, &'new str, RandomState> { >+ fn union<'a, 'new>( >+ v: Union<'a, &'static str, RandomState>, >+ ) -> Union<'a, &'new str, RandomState> { > v > } > fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { > d > } > } > > #[cfg(test)] > mod test_set { >- use super::HashSet; > use super::hash_map::RandomState; >+ use super::HashSet; > > #[test] > fn test_zero_capacities() { > type HS = HashSet<i32>; > > let s = HS::new(); > assert_eq!(s.capacity(), 0); > >diff --git a/servo/components/hashglobe/src/lib.rs b/servo/components/hashglobe/src/lib.rs >index 49038a51859d..cf6e9710f5fe 100644 >--- a/servo/components/hashglobe/src/lib.rs >+++ b/servo/components/hashglobe/src/lib.rs >@@ -39,28 +39,33 @@ pub struct FailedAllocationError { > reason: &'static str, > /// The allocation info we are requesting, if needed. > allocation_info: Option<AllocationInfo>, > } > > impl FailedAllocationError { > #[inline] > pub fn new(reason: &'static str) -> Self { >- Self { reason, allocation_info: None } >+ Self { >+ reason, >+ allocation_info: None, >+ } > } > } > > impl error::Error for FailedAllocationError { > fn description(&self) -> &str { > self.reason > } > } > > impl fmt::Display for FailedAllocationError { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > match self.allocation_info { >- Some(ref info) => { >- write!(f, "{}, allocation: (size: {}, alignment: {})", self.reason, info.size, info.alignment) >- }, >+ Some(ref info) => write!( >+ f, >+ "{}, allocation: (size: {}, alignment: {})", >+ self.reason, info.size, info.alignment >+ ), > None => self.reason.fmt(f), > } > } > } >diff --git a/servo/components/hashglobe/src/shim.rs b/servo/components/hashglobe/src/shim.rs >index 146ff851a0e5..855dbdcfa155 100644 >--- a/servo/components/hashglobe/src/shim.rs >+++ b/servo/components/hashglobe/src/shim.rs >@@ -24,21 +24,21 @@ impl<T: 'static> Unique<T> { > _marker: PhantomData, > } > } > pub fn as_ptr(&self) -> *mut T { > self.ptr.as_ptr() > } > } > >-unsafe impl<T: Send + 'static> Send for Unique<T> { } >+unsafe impl<T: Send + 'static> Send for Unique<T> {} > >-unsafe impl<T: Sync + 'static> Sync for Unique<T> { } >+unsafe impl<T: Sync + 'static> Sync for Unique<T> {} > >-pub struct Shared<T: 'static> { >+pub struct Shared<T: 'static> { > ptr: NonZeroPtr<T>, > _marker: PhantomData<T>, > // force it to be !Send/!Sync > _marker2: PhantomData<*const u8>, > } > > impl<T: 'static> Shared<T> { > pub unsafe fn new_unchecked(ptr: *mut T) -> Self { >diff --git a/servo/components/hashglobe/src/table.rs b/servo/components/hashglobe/src/table.rs >index bd801b43544f..57d5b4ae55dc 100644 >--- a/servo/components/hashglobe/src/table.rs >+++ b/servo/components/hashglobe/src/table.rs >@@ -4,23 +4,23 @@ > // > // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or > // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license > // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your > // option. This file may not be copied, modified, or distributed > // except according to those terms. > > use alloc::{alloc, dealloc}; >+use shim::{Shared, Unique}; > use std::cmp; > use std::hash::{BuildHasher, Hash, Hasher}; > use std::marker; > use std::mem::{self, align_of, size_of}; > use std::ops::{Deref, DerefMut}; > use std::ptr; >-use shim::{Unique, Shared}; > > use self::BucketState::*; > use FailedAllocationError; > > /// Integer type used for stored hash values. > /// > /// No more than bit_width(usize) bits are needed to select a bucket. > /// >@@ -198,26 +198,29 @@ impl SafeHash { > pub fn new(hash: u64) -> Self { > // We need to avoid 0 in order to prevent collisions with > // EMPTY_HASH. We can maintain our precious uniform distribution > // of initial indexes by unconditionally setting the MSB, > // effectively reducing the hashes by one bit. > // > // Truncate hash to fit in `HashUint`. > let hash_bits = size_of::<HashUint>() * 8; >- SafeHash { hash: (1 << (hash_bits - 1)) | (hash as HashUint) } >+ SafeHash { >+ hash: (1 << (hash_bits - 1)) | (hash as HashUint), >+ } > } > } > > /// We need to remove hashes of 0. That's reserved for empty buckets. > /// This function wraps up `hash_keyed` to be the only way outside this > /// module to generate a SafeHash. > pub fn make_hash<T: ?Sized, S>(hash_state: &S, t: &T) -> SafeHash >- where T: Hash, >- S: BuildHasher >+where >+ T: Hash, >+ S: BuildHasher, > { > let mut state = hash_state.build_hasher(); > t.hash(&mut state); > SafeHash::new(state.finish()) > } > > // `replace` casts a `*HashUint` to a `*SafeHash`. Since we statically > // ensure that a `FullBucket` points to an index with a non-zero hash, >@@ -289,72 +292,71 @@ impl<K, V, M> Bucket<K, V, M> { > } > /// get the table. > pub fn into_table(self) -> M { > self.table > } > } > > impl<K, V, M> Deref for FullBucket<K, V, M> >- where M: Deref<Target = RawTable<K, V>> >+where >+ M: Deref<Target = RawTable<K, V>>, > { > type Target = RawTable<K, V>; > fn deref(&self) -> &RawTable<K, V> { > &self.table > } > } > > /// `Put` is implemented for types which provide access to a table and cannot be invalidated > /// by filling a bucket. A similar implementation for `Take` is possible. > pub trait Put<K, V> { > unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V>; > } > >- > impl<'t, K, V> Put<K, V> for &'t mut RawTable<K, V> { > unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> { > *self > } > } > > impl<K, V, M> Put<K, V> for Bucket<K, V, M> >- where M: Put<K, V> >+where >+ M: Put<K, V>, > { > unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> { > self.table.borrow_table_mut() > } > } > > impl<K, V, M> Put<K, V> for FullBucket<K, V, M> >- where M: Put<K, V> >+where >+ M: Put<K, V>, > { > unsafe fn borrow_table_mut(&mut self) -> &mut RawTable<K, V> { > self.table.borrow_table_mut() > } > } > > impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> { > pub fn new(table: M, hash: SafeHash) -> Bucket<K, V, M> { > Bucket::at_index(table, hash.inspect() as usize) > } > >- pub fn new_from(r: RawBucket<K, V>, t: M) >- -> Bucket<K, V, M> >- { >- Bucket { >- raw: r, >- table: t, >- } >+ pub fn new_from(r: RawBucket<K, V>, t: M) -> Bucket<K, V, M> { >+ Bucket { raw: r, table: t } > } > > pub fn at_index(table: M, ib_index: usize) -> Bucket<K, V, M> { > // if capacity is 0, then the RawBucket will be populated with bogus pointers. > // This is an uncommon case though, so avoid it in release builds. >- debug_assert!(table.capacity() > 0, >- "Table should have capacity at this point"); >+ debug_assert!( >+ table.capacity() > 0, >+ "Table should have capacity at this point" >+ ); > let ib_index = ib_index & table.capacity_mask; > Bucket { > raw: table.raw_bucket_at(ib_index), > table, > } > } > > pub fn first(table: M) -> Bucket<K, V, M> { >@@ -399,28 +401,24 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> { > } > > /// Reads a bucket at a given index, returning an enum indicating whether > /// it's initialized or not. You need to match on this enum to get > /// the appropriate types to call most of the other functions in > /// this module. > pub fn peek(self) -> BucketState<K, V, M> { > match unsafe { *self.raw.hash() } { >- EMPTY_BUCKET => { >- Empty(EmptyBucket { >- raw: self.raw, >- table: self.table, >- }) >- } >- _ => { >- Full(FullBucket { >- raw: self.raw, >- table: self.table, >- }) >- } >+ EMPTY_BUCKET => Empty(EmptyBucket { >+ raw: self.raw, >+ table: self.table, >+ }), >+ _ => Full(FullBucket { >+ raw: self.raw, >+ table: self.table, >+ }), > } > } > > /// Modifies the bucket in place to make it point to the next slot. > pub fn next(&mut self) { > self.raw.idx = self.raw.idx.wrapping_add(1) & self.table.capacity_mask; > } > >@@ -448,29 +446,25 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> { > > pub fn gap_peek(self) -> Result<GapThenFull<K, V, M>, Bucket<K, V, M>> { > let gap = EmptyBucket { > raw: self.raw, > table: (), > }; > > match self.next().peek() { >- Full(bucket) => { >- Ok(GapThenFull { >- gap, >- full: bucket, >- }) >- } >+ Full(bucket) => Ok(GapThenFull { gap, full: bucket }), > Empty(e) => Err(e.into_bucket()), > } > } > } > > impl<K, V, M> EmptyBucket<K, V, M> >- where M: Put<K, V> >+where >+ M: Put<K, V>, > { > /// Puts given key and value pair, along with the key's hash, > /// into this bucket in the hashtable. Note how `self` is 'moved' into > /// this function, because this slot will no longer be empty when > /// we return! A `FullBucket` is returned for later use, pointing to > /// the newly-filled slot in the hashtable. > /// > /// Use `make_hash` to construct a `SafeHash` to pass to this function. >@@ -523,17 +517,21 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> FullBucket<K, V, M> { > // Calculates the distance one has to travel when going from > // `hash mod capacity` onwards to `idx mod capacity`, wrapping around > // if the destination is not reached before the end of the table. > (self.raw.idx.wrapping_sub(self.hash().inspect() as usize)) & self.table.capacity_mask > } > > #[inline] > pub fn hash(&self) -> SafeHash { >- unsafe { SafeHash { hash: *self.raw.hash() } } >+ unsafe { >+ SafeHash { >+ hash: *self.raw.hash(), >+ } >+ } > } > > /// Gets references to the key and value at a given index. > pub fn read(&self) -> (&K, &V) { > unsafe { > let pair_ptr = self.raw.pair(); > (&(*pair_ptr).0, &(*pair_ptr).1) > } >@@ -549,84 +547,91 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> { > /// This works similarly to `put`, building an `EmptyBucket` out of the > /// taken bucket. > pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) { > self.table.size -= 1; > > unsafe { > *self.raw.hash() = EMPTY_BUCKET; > let (k, v) = ptr::read(self.raw.pair()); >- (EmptyBucket { >- raw: self.raw, >- table: self.table, >- }, >- k, >- v) >+ ( >+ EmptyBucket { >+ raw: self.raw, >+ table: self.table, >+ }, >+ k, >+ v, >+ ) > } > } > } > > // This use of `Put` is misleading and restrictive, but safe and sufficient for our use cases > // where `M` is a full bucket or table reference type with mutable access to the table. > impl<K, V, M> FullBucket<K, V, M> >- where M: Put<K, V> >+where >+ M: Put<K, V>, > { > pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) { > unsafe { > let old_hash = ptr::replace(self.raw.hash() as *mut SafeHash, h); > let (old_key, old_val) = ptr::replace(self.raw.pair(), (k, v)); > > (old_hash, old_key, old_val) > } > } > } > > impl<K, V, M> FullBucket<K, V, M> >- where M: Deref<Target = RawTable<K, V>> + DerefMut >+where >+ M: Deref<Target = RawTable<K, V>> + DerefMut, > { > /// Gets mutable references to the key and value at a given index. > pub fn read_mut(&mut self) -> (&mut K, &mut V) { > unsafe { > let pair_ptr = self.raw.pair(); > (&mut (*pair_ptr).0, &mut (*pair_ptr).1) > } > } > } > > impl<'t, K, V, M> FullBucket<K, V, M> >- where M: Deref<Target = RawTable<K, V>> + 't >+where >+ M: Deref<Target = RawTable<K, V>> + 't, > { > /// Exchange a bucket state for immutable references into the table. > /// Because the underlying reference to the table is also consumed, > /// no further changes to the structure of the table are possible; > /// in exchange for this, the returned references have a longer lifetime > /// than the references returned by `read()`. > pub fn into_refs(self) -> (&'t K, &'t V) { > unsafe { > let pair_ptr = self.raw.pair(); > (&(*pair_ptr).0, &(*pair_ptr).1) > } > } > } > > impl<'t, K, V, M> FullBucket<K, V, M> >- where M: Deref<Target = RawTable<K, V>> + DerefMut + 't >+where >+ M: Deref<Target = RawTable<K, V>> + DerefMut + 't, > { > /// This works similarly to `into_refs`, exchanging a bucket state > /// for mutable references into the table. > pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) { > unsafe { > let pair_ptr = self.raw.pair(); > (&mut (*pair_ptr).0, &mut (*pair_ptr).1) > } > } > } > > impl<K, V, M> GapThenFull<K, V, M> >- where M: Deref<Target = RawTable<K, V>> >+where >+ M: Deref<Target = RawTable<K, V>>, > { > #[inline] > pub fn full(&self) -> &FullBucket<K, V, M> { > &self.full > } > > pub fn into_table(self) -> M { > self.full.into_table() >@@ -650,17 +655,16 @@ impl<K, V, M> GapThenFull<K, V, M> > > Ok(self) > } > Empty(b) => Err(b.into_bucket()), > } > } > } > >- > /// Rounds up to a multiple of a power of two. Returns the closest multiple > /// of `target_alignment` that is higher or equal to `unrounded`. > /// > /// # Panics > /// > /// Panics if `target_alignment` is not a power of two. > #[inline] > fn round_up_to_next(unrounded: usize, target_alignment: usize) -> usize { >@@ -676,33 +680,35 @@ fn test_rounding() { > assert_eq!(round_up_to_next(3, 4), 4); > assert_eq!(round_up_to_next(4, 4), 4); > assert_eq!(round_up_to_next(5, 4), 8); > } > > // Returns a tuple of (pairs_offset, end_of_pairs_offset), > // from the start of a mallocated array. > #[inline] >-fn calculate_offsets(hashes_size: usize, >- pairs_size: usize, >- pairs_align: usize) >- -> (usize, usize, bool) { >+fn calculate_offsets( >+ hashes_size: usize, >+ pairs_size: usize, >+ pairs_align: usize, >+) -> (usize, usize, bool) { > let pairs_offset = round_up_to_next(hashes_size, pairs_align); > let (end_of_pairs, oflo) = pairs_offset.overflowing_add(pairs_size); > > (pairs_offset, end_of_pairs, oflo) > } > > // Returns a tuple of (minimum required malloc alignment, hash_offset, > // array_size), from the start of a mallocated array. >-fn calculate_allocation(hash_size: usize, >- hash_align: usize, >- pairs_size: usize, >- pairs_align: usize) >- -> (usize, usize, usize, bool) { >+fn calculate_allocation( >+ hash_size: usize, >+ hash_align: usize, >+ pairs_size: usize, >+ pairs_align: usize, >+) -> (usize, usize, usize, bool) { > let hash_offset = 0; > let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align); > > let align = cmp::max(hash_align, pairs_align); > > (align, hash_offset, end_of_pairs, oflo) > } > >@@ -723,17 +729,19 @@ impl<K, V> RawTable<K, V> { > table > } else { > libc::abort(); > } > } > > /// Does not initialize the buckets. The caller should ensure they, > /// at the very least, set every hash to EMPTY_BUCKET. >- unsafe fn try_new_uninitialized(capacity: usize) -> Result<RawTable<K, V>, FailedAllocationError> { >+ unsafe fn try_new_uninitialized( >+ capacity: usize, >+ ) -> Result<RawTable<K, V>, FailedAllocationError> { > if capacity == 0 { > return Ok(RawTable { > size: 0, > capacity_mask: capacity.wrapping_sub(1), > hashes: TaggedHashUintPtr::new(EMPTY as *mut HashUint), > marker: marker::PhantomData, > }); > } >@@ -746,39 +754,48 @@ impl<K, V> RawTable<K, V> { > // Allocating hashmaps is a little tricky. We need to allocate two > // arrays, but since we know their sizes and alignments up front, > // we just allocate a single array, and then have the subarrays > // point into it. > // > // This is great in theory, but in practice getting the alignment > // right is a little subtle. Therefore, calculating offsets has been > // factored out into a different function. >- let (alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size, >- align_of::<HashUint>(), >- pairs_size, >- align_of::<(K, V)>()); >+ let (alignment, hash_offset, size, oflo) = calculate_allocation( >+ hashes_size, >+ align_of::<HashUint>(), >+ pairs_size, >+ align_of::<(K, V)>(), >+ ); > > if oflo { >- return Err(FailedAllocationError::new("capacity overflow when allocating RawTable" )); >+ return Err(FailedAllocationError::new( >+ "capacity overflow when allocating RawTable", >+ )); > } > > // One check for overflow that covers calculation and rounding of size. >- let size_of_bucket = size_of::<HashUint>().checked_add(size_of::<(K, V)>()).unwrap(); >+ let size_of_bucket = size_of::<HashUint>() >+ .checked_add(size_of::<(K, V)>()) >+ .unwrap(); > > let cap_bytes = capacity.checked_mul(size_of_bucket); > > if let Some(cap_bytes) = cap_bytes { > if size < cap_bytes { >- return Err(FailedAllocationError::new("capacity overflow when allocating RawTable")); >+ return Err(FailedAllocationError::new( >+ "capacity overflow when allocating RawTable", >+ )); > } > } else { >- return Err(FailedAllocationError::new("capacity overflow when allocating RawTable")); >+ return Err(FailedAllocationError::new( >+ "capacity overflow when allocating RawTable", >+ )); > } > >- > // FORK NOTE: Uses alloc shim instead of Heap.alloc > let buffer = alloc(size, alignment); > > if buffer.is_null() { > use AllocationInfo; > return Err(FailedAllocationError { > reason: "out of memory when allocating RawTable", > allocation_info: Some(AllocationInfo { size, alignment }), >@@ -852,30 +869,34 @@ impl<K, V> RawTable<K, V> { > pub fn iter_mut(&mut self) -> IterMut<K, V> { > IterMut { > iter: self.raw_buckets(), > _marker: marker::PhantomData, > } > } > > pub fn into_iter(self) -> IntoIter<K, V> { >- let RawBuckets { raw, elems_left, .. } = self.raw_buckets(); >+ let RawBuckets { >+ raw, elems_left, .. >+ } = self.raw_buckets(); > // Replace the marker regardless of lifetime bounds on parameters. > IntoIter { > iter: RawBuckets { > raw, > elems_left, > marker: marker::PhantomData, > }, > table: self, > } > } > > pub fn drain(&mut self) -> Drain<K, V> { >- let RawBuckets { raw, elems_left, .. } = self.raw_buckets(); >+ let RawBuckets { >+ raw, elems_left, .. >+ } = self.raw_buckets(); > // Replace the marker regardless of lifetime bounds on parameters. > Drain { > iter: RawBuckets { > raw, > elems_left, > marker: marker::PhantomData, > }, > table: Shared::from(self), >@@ -932,17 +953,16 @@ impl<'a, K, V> Clone for RawBuckets<'a, K, V> { > RawBuckets { > raw: self.raw, > elems_left: self.elems_left, > marker: marker::PhantomData, > } > } > } > >- > impl<'a, K, V> Iterator for RawBuckets<'a, K, V> { > type Item = RawBucket<K, V>; > > fn next(&mut self) -> Option<RawBucket<K, V>> { > if self.elems_left == 0 { > return None; > } > >@@ -1107,22 +1127,26 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> { > } > } > > impl<'a, K, V> Iterator for Drain<'a, K, V> { > type Item = (SafeHash, K, V); > > #[inline] > fn next(&mut self) -> Option<(SafeHash, K, V)> { >- self.iter.next().map(|raw| { >- unsafe { >- self.table.as_mut().size -= 1; >- let (k, v) = ptr::read(raw.pair()); >- (SafeHash { hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET) }, k, v) >- } >+ self.iter.next().map(|raw| unsafe { >+ self.table.as_mut().size -= 1; >+ let (k, v) = ptr::read(raw.pair()); >+ ( >+ SafeHash { >+ hash: ptr::replace(&mut *raw.hash(), EMPTY_BUCKET), >+ }, >+ k, >+ v, >+ ) > }) > } > > fn size_hint(&self) -> (usize, Option<usize>) { > self.iter.size_hint() > } > } > >@@ -1176,27 +1200,29 @@ impl<K, V> Drop for RawTable<K, V> { > // This is done in reverse because we've likely partially taken > // some elements out with `.into_iter()` from the front. > // Check if the size is 0, so we don't do a useless scan when > // dropping empty tables such as on resize. > // Also avoid double drop of elements that have been already moved out. > unsafe { > // FORK NOTE: Can't needs_drop on stable > // if needs_drop::<(K, V)>() { >- // avoid linear runtime for types that don't need drop >- self.rev_drop_buckets(); >+ // avoid linear runtime for types that don't need drop >+ self.rev_drop_buckets(); > // } > } > > let hashes_size = self.capacity() * size_of::<HashUint>(); > let pairs_size = self.capacity() * size_of::<(K, V)>(); >- let (align, _, _, oflo) = calculate_allocation(hashes_size, >- align_of::<HashUint>(), >- pairs_size, >- align_of::<(K, V)>()); >+ let (align, _, _, oflo) = calculate_allocation( >+ hashes_size, >+ align_of::<HashUint>(), >+ pairs_size, >+ align_of::<(K, V)>(), >+ ); > > debug_assert!(!oflo, "should be impossible"); > > unsafe { > dealloc(self.hashes.ptr() as *mut u8, align); > // Remember how everything was allocated out of one buffer > // during initialization? We only need one call to free here. > } >diff --git a/servo/components/malloc_size_of/lib.rs b/servo/components/malloc_size_of/lib.rs >index f4774d66a3e6..2ec2b1ff7756 100644 >--- a/servo/components/malloc_size_of/lib.rs >+++ b/servo/components/malloc_size_of/lib.rs >@@ -73,18 +73,18 @@ extern crate void; > extern crate webrender_api; > #[cfg(feature = "servo")] > extern crate xml5ever; > > #[cfg(feature = "servo")] > use serde_bytes::ByteBuf; > use std::hash::{BuildHasher, Hash}; > use std::mem::size_of; >-use std::ops::{Deref, DerefMut}; > use std::ops::Range; >+use std::ops::{Deref, DerefMut}; > use std::os::raw::c_void; > use void::Void; > > /// A C function that takes a pointer to a heap allocation and returns its size. > type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize; > > /// A closure implementing a stateful predicate on pointers. > type VoidPtrToBoolFnMut = FnMut(*const c_void) -> bool; >@@ -102,19 +102,21 @@ pub struct MallocSizeOfOps { > > /// Check if a pointer has been seen before, and remember it for next time. > /// Useful when measuring `Rc`s and `Arc`s. Optional, because many places > /// don't need it. > have_seen_ptr_op: Option<Box<VoidPtrToBoolFnMut>>, > } > > impl MallocSizeOfOps { >- pub fn new(size_of: VoidPtrToSizeFn, >- malloc_enclosing_size_of: Option<VoidPtrToSizeFn>, >- have_seen_ptr: Option<Box<VoidPtrToBoolFnMut>>) -> Self { >+ pub fn new( >+ size_of: VoidPtrToSizeFn, >+ malloc_enclosing_size_of: Option<VoidPtrToSizeFn>, >+ have_seen_ptr: Option<Box<VoidPtrToBoolFnMut>>, >+ ) -> Self { > MallocSizeOfOps { > size_of_op: size_of, > enclosing_size_of_op: malloc_enclosing_size_of, > have_seen_ptr_op: have_seen_ptr, > } > } > > /// Check if an allocation is empty. This relies on knowledge of how Rust >@@ -122,17 +124,17 @@ impl MallocSizeOfOps { > fn is_empty<T: ?Sized>(ptr: *const T) -> bool { > // The correct condition is this: > // `ptr as usize <= ::std::mem::align_of::<T>()` > // But we can't call align_of() on a ?Sized T. So we approximate it > // with the following. 256 is large enough that it should always be > // larger than the required alignment, but small enough that it is > // always in the first page of memory and therefore not a legitimate > // address. >- return ptr as *const usize as usize <= 256 >+ return ptr as *const usize as usize <= 256; > } > > /// Call `size_of_op` on `ptr`, first checking that the allocation isn't > /// empty, because some types (such as `Vec`) utilize empty allocations. > pub unsafe fn malloc_size_of<T: ?Sized>(&self, ptr: *const T) -> usize { > if MallocSizeOfOps::is_empty(ptr) { > 0 > } else { >@@ -149,17 +151,20 @@ impl MallocSizeOfOps { > /// must not be empty. > pub unsafe fn malloc_enclosing_size_of<T>(&self, ptr: *const T) -> usize { > assert!(!MallocSizeOfOps::is_empty(ptr)); > (self.enclosing_size_of_op.unwrap())(ptr as *const c_void) > } > > /// Call `have_seen_ptr_op` on `ptr`. > pub fn have_seen_ptr<T>(&mut self, ptr: *const T) -> bool { >- let have_seen_ptr_op = self.have_seen_ptr_op.as_mut().expect("missing have_seen_ptr_op"); >+ let have_seen_ptr_op = self >+ .have_seen_ptr_op >+ .as_mut() >+ .expect("missing have_seen_ptr_op"); > have_seen_ptr_op(ptr as *const c_void) > } > } > > /// Trait for measuring the "deep" heap usage of a data structure. This is the > /// most commonly-used of the traits. > pub trait MallocSizeOf { > /// Measure the heap usage of all descendant heap-allocated structures, but >@@ -252,33 +257,42 @@ impl<T: MallocSizeOf> MallocSizeOf for thin_slice::ThinBoxedSlice<T> { > > impl MallocSizeOf for () { > fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { > 0 > } > } > > impl<T1, T2> MallocSizeOf for (T1, T2) >- where T1: MallocSizeOf, T2: MallocSizeOf >+where >+ T1: MallocSizeOf, >+ T2: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.0.size_of(ops) + self.1.size_of(ops) > } > } > > impl<T1, T2, T3> MallocSizeOf for (T1, T2, T3) >- where T1: MallocSizeOf, T2: MallocSizeOf, T3: MallocSizeOf >+where >+ T1: MallocSizeOf, >+ T2: MallocSizeOf, >+ T3: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) > } > } > > impl<T1, T2, T3, T4> MallocSizeOf for (T1, T2, T3, T4) >- where T1: MallocSizeOf, T2: MallocSizeOf, T3: MallocSizeOf, T4: MallocSizeOf >+where >+ T1: MallocSizeOf, >+ T2: MallocSizeOf, >+ T3: MallocSizeOf, >+ T4: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) + self.3.size_of(ops) > } > } > > impl<T: MallocSizeOf> MallocSizeOf for Option<T> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >@@ -307,17 +321,18 @@ impl<T: MallocSizeOf + Copy> MallocSizeOf for std::cell::Cell<T> { > > impl<T: MallocSizeOf> MallocSizeOf for std::cell::RefCell<T> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.borrow().size_of(ops) > } > } > > impl<'a, B: ?Sized + ToOwned> MallocSizeOf for std::borrow::Cow<'a, B> >- where B::Owned: MallocSizeOf >+where >+ B::Owned: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > match *self { > std::borrow::Cow::Borrowed(_) => 0, > std::borrow::Cow::Owned(ref b) => b.size_of(ops), > } > } > } >@@ -399,178 +414,199 @@ impl<A: smallvec::Array> MallocShallowSizeOf for smallvec::SmallVec<A> { > unsafe { ops.malloc_size_of(self.as_ptr()) } > } else { > 0 > } > } > } > > impl<A> MallocSizeOf for smallvec::SmallVec<A> >- where A: smallvec::Array, >- A::Item: MallocSizeOf >+where >+ A: smallvec::Array, >+ A::Item: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = self.shallow_size_of(ops); > for elem in self.iter() { > n += elem.size_of(ops); > } > n > } > } > > impl<T, S> MallocShallowSizeOf for std::collections::HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > if ops.has_malloc_enclosing_size_of() { > // The first value from the iterator gives us an interior pointer. > // `ops.malloc_enclosing_size_of()` then gives us the storage size. > // This assumes that the `HashSet`'s contents (values and hashes) > // are all stored in a single contiguous heap allocation. >- self.iter().next().map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) }) >+ self.iter() >+ .next() >+ .map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) }) > } else { > // An estimate. > self.capacity() * (size_of::<T>() + size_of::<usize>()) > } > } > } > > impl<T, S> MallocSizeOf for std::collections::HashSet<T, S> >- where T: Eq + Hash + MallocSizeOf, >- S: BuildHasher, >+where >+ T: Eq + Hash + MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = self.shallow_size_of(ops); > for t in self.iter() { > n += t.size_of(ops); > } > n > } > } > > impl<T, S> MallocShallowSizeOf for hashglobe::hash_set::HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > // See the implementation for std::collections::HashSet for details. > if ops.has_malloc_enclosing_size_of() { >- self.iter().next().map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) }) >+ self.iter() >+ .next() >+ .map_or(0, |t| unsafe { ops.malloc_enclosing_size_of(t) }) > } else { > self.capacity() * (size_of::<T>() + size_of::<usize>()) > } > } > } > > impl<T, S> MallocSizeOf for hashglobe::hash_set::HashSet<T, S> >- where T: Eq + Hash + MallocSizeOf, >- S: BuildHasher, >+where >+ T: Eq + Hash + MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = self.shallow_size_of(ops); > for t in self.iter() { > n += t.size_of(ops); > } > n > } > } > > impl<T, S> MallocShallowSizeOf for hashglobe::fake::HashSet<T, S> >- where T: Eq + Hash, >- S: BuildHasher, >+where >+ T: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > use std::ops::Deref; > self.deref().shallow_size_of(ops) > } > } > > impl<T, S> MallocSizeOf for hashglobe::fake::HashSet<T, S> >- where T: Eq + Hash + MallocSizeOf, >- S: BuildHasher, >+where >+ T: Eq + Hash + MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > use std::ops::Deref; > self.deref().size_of(ops) > } > } > > impl<K, V, S> MallocShallowSizeOf for std::collections::HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > // See the implementation for std::collections::HashSet for details. > if ops.has_malloc_enclosing_size_of() { >- self.values().next().map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) >+ self.values() >+ .next() >+ .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) > } else { > self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>()) > } > } > } > > impl<K, V, S> MallocSizeOf for std::collections::HashMap<K, V, S> >- where K: Eq + Hash + MallocSizeOf, >- V: MallocSizeOf, >- S: BuildHasher, >+where >+ K: Eq + Hash + MallocSizeOf, >+ V: MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = self.shallow_size_of(ops); > for (k, v) in self.iter() { > n += k.size_of(ops); > n += v.size_of(ops); > } > n > } > } > > impl<K, V, S> MallocShallowSizeOf for hashglobe::hash_map::HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > // See the implementation for std::collections::HashSet for details. > if ops.has_malloc_enclosing_size_of() { >- self.values().next().map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) >+ self.values() >+ .next() >+ .map_or(0, |v| unsafe { ops.malloc_enclosing_size_of(v) }) > } else { > self.capacity() * (size_of::<V>() + size_of::<K>() + size_of::<usize>()) > } > } > } > > impl<K, V, S> MallocSizeOf for hashglobe::hash_map::HashMap<K, V, S> >- where K: Eq + Hash + MallocSizeOf, >- V: MallocSizeOf, >- S: BuildHasher, >+where >+ K: Eq + Hash + MallocSizeOf, >+ V: MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = self.shallow_size_of(ops); > for (k, v) in self.iter() { > n += k.size_of(ops); > n += v.size_of(ops); > } > n > } > } > > impl<K, V, S> MallocShallowSizeOf for hashglobe::fake::HashMap<K, V, S> >- where K: Eq + Hash, >- S: BuildHasher, >+where >+ K: Eq + Hash, >+ S: BuildHasher, > { > fn shallow_size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > use std::ops::Deref; > self.deref().shallow_size_of(ops) > } > } > > impl<K, V, S> MallocSizeOf for hashglobe::fake::HashMap<K, V, S> >- where K: Eq + Hash + MallocSizeOf, >- V: MallocSizeOf, >- S: BuildHasher, >+where >+ K: Eq + Hash + MallocSizeOf, >+ V: MallocSizeOf, >+ S: BuildHasher, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > use std::ops::Deref; > self.deref().size_of(ops) > } > } > > // PhantomData is always 0. >@@ -662,63 +698,75 @@ impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedPoint2D<T, U> { > impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedRect<T, U> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.origin.size_of(ops) + self.size.size_of(ops) > } > } > > impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSideOffsets2D<T, U> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >- self.top.size_of(ops) + self.right.size_of(ops) + >- self.bottom.size_of(ops) + self.left.size_of(ops) >+ self.top.size_of(ops) >+ + self.right.size_of(ops) >+ + self.bottom.size_of(ops) >+ + self.left.size_of(ops) > } > } > > impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedSize2D<T, U> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.width.size_of(ops) + self.height.size_of(ops) > } > } > > impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform2D<T, Src, Dst> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >- self.m11.size_of(ops) + self.m12.size_of(ops) + >- self.m21.size_of(ops) + self.m22.size_of(ops) + >- self.m31.size_of(ops) + self.m32.size_of(ops) >+ self.m11.size_of(ops) >+ + self.m12.size_of(ops) >+ + self.m21.size_of(ops) >+ + self.m22.size_of(ops) >+ + self.m31.size_of(ops) >+ + self.m32.size_of(ops) > } > } > > impl<T: MallocSizeOf, Src, Dst> MallocSizeOf for euclid::TypedTransform3D<T, Src, Dst> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >- self.m11.size_of(ops) + self.m12.size_of(ops) + >- self.m13.size_of(ops) + self.m14.size_of(ops) + >- self.m21.size_of(ops) + self.m22.size_of(ops) + >- self.m23.size_of(ops) + self.m24.size_of(ops) + >- self.m31.size_of(ops) + self.m32.size_of(ops) + >- self.m33.size_of(ops) + self.m34.size_of(ops) + >- self.m41.size_of(ops) + self.m42.size_of(ops) + >- self.m43.size_of(ops) + self.m44.size_of(ops) >+ self.m11.size_of(ops) >+ + self.m12.size_of(ops) >+ + self.m13.size_of(ops) >+ + self.m14.size_of(ops) >+ + self.m21.size_of(ops) >+ + self.m22.size_of(ops) >+ + self.m23.size_of(ops) >+ + self.m24.size_of(ops) >+ + self.m31.size_of(ops) >+ + self.m32.size_of(ops) >+ + self.m33.size_of(ops) >+ + self.m34.size_of(ops) >+ + self.m41.size_of(ops) >+ + self.m42.size_of(ops) >+ + self.m43.size_of(ops) >+ + self.m44.size_of(ops) > } > } > > impl<T: MallocSizeOf, U> MallocSizeOf for euclid::TypedVector2D<T, U> { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.x.size_of(ops) + self.y.size_of(ops) > } > } > > impl MallocSizeOf for selectors::parser::AncestorHashes { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let selectors::parser::AncestorHashes { ref packed_hashes } = *self; > packed_hashes.size_of(ops) > } > } > >-impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf >- for selectors::parser::Selector<Impl> >+impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf for selectors::parser::Selector<Impl> > where > Impl::NonTSPseudoClass: MallocSizeOf, > Impl::PseudoElement: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > let mut n = 0; > > // It's OK to measure this ThinArc directly because it's the >@@ -728,67 +776,57 @@ where > for component in self.iter_raw_match_order() { > n += component.size_of(ops); > } > > n > } > } > >-impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf >- for selectors::parser::Component<Impl> >+impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf for selectors::parser::Component<Impl> > where > Impl::NonTSPseudoClass: MallocSizeOf, > Impl::PseudoElement: MallocSizeOf, > { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > use selectors::parser::Component; > > match self { >- Component::AttributeOther(ref attr_selector) => { >- attr_selector.size_of(ops) >- } >- Component::Negation(ref components) => { >- components.size_of(ops) >- } >- Component::NonTSPseudoClass(ref pseudo) => { >- (*pseudo).size_of(ops) >- } >- Component::Slotted(ref selector) | >- Component::Host(Some(ref selector)) => { >+ Component::AttributeOther(ref attr_selector) => attr_selector.size_of(ops), >+ Component::Negation(ref components) => components.size_of(ops), >+ Component::NonTSPseudoClass(ref pseudo) => (*pseudo).size_of(ops), >+ Component::Slotted(ref selector) | Component::Host(Some(ref selector)) => { > selector.size_of(ops) > } >- Component::PseudoElement(ref pseudo) => { >- (*pseudo).size_of(ops) >- } >- Component::Combinator(..) | >- Component::ExplicitAnyNamespace | >- Component::ExplicitNoNamespace | >- Component::DefaultNamespace(..) | >- Component::Namespace(..) | >- Component::ExplicitUniversalType | >- Component::LocalName(..) | >- Component::ID(..) | >- Component::Class(..) | >- Component::AttributeInNoNamespaceExists { .. } | >- Component::AttributeInNoNamespace { .. } | >- Component::FirstChild | >- Component::LastChild | >- Component::OnlyChild | >- Component::Root | >- Component::Empty | >- Component::Scope | >- Component::NthChild(..) | >- Component::NthLastChild(..) | >- Component::NthOfType(..) | >- Component::NthLastOfType(..) | >- Component::FirstOfType | >- Component::LastOfType | >- Component::OnlyOfType | >- Component::Host(None) => 0, >+ Component::PseudoElement(ref pseudo) => (*pseudo).size_of(ops), >+ Component::Combinator(..) >+ | Component::ExplicitAnyNamespace >+ | Component::ExplicitNoNamespace >+ | Component::DefaultNamespace(..) >+ | Component::Namespace(..) >+ | Component::ExplicitUniversalType >+ | Component::LocalName(..) >+ | Component::ID(..) >+ | Component::Class(..) >+ | Component::AttributeInNoNamespaceExists { .. } >+ | Component::AttributeInNoNamespace { .. } >+ | Component::FirstChild >+ | Component::LastChild >+ | Component::OnlyChild >+ | Component::Root >+ | Component::Empty >+ | Component::Scope >+ | Component::NthChild(..) >+ | Component::NthLastChild(..) >+ | Component::NthOfType(..) >+ | Component::NthLastOfType(..) >+ | Component::FirstOfType >+ | Component::LastOfType >+ | Component::OnlyOfType >+ | Component::Host(None) => 0, > } > } > } > > impl<Impl: selectors::parser::SelectorImpl> MallocSizeOf > for selectors::attr::AttrSelectorWithOptionalNamespace<Impl> > { > fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { >@@ -845,17 +883,20 @@ macro_rules! malloc_size_of_is_0( > ); > > malloc_size_of_is_0!(bool, char, str); > malloc_size_of_is_0!(u8, u16, u32, u64, usize); > malloc_size_of_is_0!(i8, i16, i32, i64, isize); > malloc_size_of_is_0!(f32, f64); > > malloc_size_of_is_0!(std::sync::atomic::AtomicBool); >-malloc_size_of_is_0!(std::sync::atomic::AtomicIsize, std::sync::atomic::AtomicUsize); >+malloc_size_of_is_0!( >+ std::sync::atomic::AtomicIsize, >+ std::sync::atomic::AtomicUsize >+); > > malloc_size_of_is_0!(Range<u8>, Range<u16>, Range<u32>, Range<u64>, Range<usize>); > malloc_size_of_is_0!(Range<i8>, Range<i16>, Range<i32>, Range<i64>, Range<isize>); > malloc_size_of_is_0!(Range<f32>, Range<f64>); > > malloc_size_of_is_0!(app_units::Au); > > malloc_size_of_is_0!(cssparser::RGBA, cssparser::TokenSerializationType); >@@ -914,19 +955,17 @@ malloc_size_of_is_0!(webrender_api::ScrollSensitivity); > #[cfg(feature = "webrender_api")] > malloc_size_of_is_0!(webrender_api::StickyOffsetBounds); > #[cfg(feature = "webrender_api")] > malloc_size_of_is_0!(webrender_api::TransformStyle); > > #[cfg(feature = "servo")] > impl MallocSizeOf for xml5ever::QualName { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >- self.prefix.size_of(ops) + >- self.ns.size_of(ops) + >- self.local.size_of(ops) >+ self.prefix.size_of(ops) + self.ns.size_of(ops) + self.local.size_of(ops) > } > } > > #[cfg(feature = "servo")] > impl MallocSizeOf for hyper::header::Headers { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.iter().fold(0, |acc, x| { > let name = x.name(); >@@ -941,19 +980,17 @@ impl MallocSizeOf for hyper::header::ContentType { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.0.size_of(ops) > } > } > > #[cfg(feature = "servo")] > impl MallocSizeOf for hyper::mime::Mime { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { >- self.0.size_of(ops) + >- self.1.size_of(ops) + >- self.2.size_of(ops) >+ self.0.size_of(ops) + self.1.size_of(ops) + self.2.size_of(ops) > } > } > > #[cfg(feature = "servo")] > impl MallocSizeOf for hyper::mime::Attr { > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > match *self { > hyper::mime::Attr::Ext(ref s) => s.size_of(ops), >@@ -970,20 +1007,22 @@ impl MallocSizeOf for hyper::mime::Value { > } > > #[cfg(feature = "servo")] > malloc_size_of_is_0!(time::Duration); > #[cfg(feature = "servo")] > malloc_size_of_is_0!(time::Tm); > > #[cfg(feature = "servo")] >-impl<T> MallocSizeOf for hyper_serde::Serde<T> where >- for <'de> hyper_serde::De<T>: serde::Deserialize<'de>, >- for <'a> hyper_serde::Ser<'a, T>: serde::Serialize, >- T: MallocSizeOf { >+impl<T> MallocSizeOf for hyper_serde::Serde<T> >+where >+ for<'de> hyper_serde::De<T>: serde::Deserialize<'de>, >+ for<'a> hyper_serde::Ser<'a, T>: serde::Serialize, >+ T: MallocSizeOf, >+{ > fn size_of(&self, ops: &mut MallocSizeOfOps) -> usize { > self.0.size_of(ops) > } > } > > // Placeholder for unique case where internals of Sender cannot be measured. > // malloc size of is 0 macro complains about type supplied! > impl<T> MallocSizeOf for std::sync::mpsc::Sender<T> { >@@ -1000,17 +1039,17 @@ impl MallocSizeOf for hyper::status::StatusCode { > _ => 0, > } > } > } > > /// Measurable that defers to inner value and used to verify MallocSizeOf implementation in a > /// struct. > #[derive(Clone)] >-pub struct Measurable<T: MallocSizeOf> (pub T); >+pub struct Measurable<T: MallocSizeOf>(pub T); > > impl<T: MallocSizeOf> Deref for Measurable<T> { > type Target = T; > > fn deref(&self) -> &T { > &self.0 > } > } >diff --git a/servo/components/malloc_size_of_derive/lib.rs b/servo/components/malloc_size_of_derive/lib.rs >index 20e9225277ee..042103a98781 100644 >--- a/servo/components/malloc_size_of_derive/lib.rs >+++ b/servo/components/malloc_size_of_derive/lib.rs >@@ -6,35 +6,46 @@ > // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license > // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your > // option. This file may not be copied, modified, or distributed > // except according to those terms. > > //! A crate for deriving the MallocSizeOf trait. > > extern crate quote; >-#[macro_use] extern crate syn; >-#[macro_use] extern crate synstructure; >+#[macro_use] >+extern crate syn; >+#[macro_use] >+extern crate synstructure; > > #[cfg(not(test))] > decl_derive!([MallocSizeOf, attributes(ignore_malloc_size_of)] => malloc_size_of_derive); > > fn malloc_size_of_derive(s: synstructure::Structure) -> quote::Tokens { > let match_body = s.each(|binding| { >- let ignore = binding.ast().attrs.iter().any(|attr| match attr.interpret_meta().unwrap() { >- syn::Meta::Word(ref ident) | >- syn::Meta::List(syn::MetaList { ref ident, .. }) if ident == "ignore_malloc_size_of" => { >- panic!("#[ignore_malloc_size_of] should have an explanation, \ >- e.g. #[ignore_malloc_size_of = \"because reasons\"]"); >- } >- syn::Meta::NameValue(syn::MetaNameValue { ref ident, .. }) if ident == "ignore_malloc_size_of" => { >- true >- } >- _ => false, >- }); >+ let ignore = binding >+ .ast() >+ .attrs >+ .iter() >+ .any(|attr| match attr.interpret_meta().unwrap() { >+ syn::Meta::Word(ref ident) | syn::Meta::List(syn::MetaList { ref ident, .. }) >+ if ident == "ignore_malloc_size_of" => >+ { >+ panic!( >+ "#[ignore_malloc_size_of] should have an explanation, \ >+ e.g. #[ignore_malloc_size_of = \"because reasons\"]" >+ ); >+ } >+ syn::Meta::NameValue(syn::MetaNameValue { ref ident, .. }) >+ if ident == "ignore_malloc_size_of" => >+ { >+ true >+ } >+ _ => false, >+ }); > if ignore { > None > } else if let syn::Type::Array(..) = binding.ast().ty { > Some(quote! { > for item in #binding.iter() { > sum += ::malloc_size_of::MallocSizeOf::size_of(item, ops); > } > }) >@@ -46,17 +57,19 @@ fn malloc_size_of_derive(s: synstructure::Structure) -> quote::Tokens { > }); > > let ast = s.ast(); > let name = &ast.ident; > let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); > let mut where_clause = where_clause.unwrap_or(&parse_quote!(where)).clone(); > for param in ast.generics.type_params() { > let ident = param.ident; >- where_clause.predicates.push(parse_quote!(#ident: ::malloc_size_of::MallocSizeOf)); >+ where_clause >+ .predicates >+ .push(parse_quote!(#ident: ::malloc_size_of::MallocSizeOf)); > } > > let tokens = quote! { > impl #impl_generics ::malloc_size_of::MallocSizeOf for #name #ty_generics #where_clause { > #[inline] > #[allow(unused_variables, unused_mut, unreachable_code)] > fn size_of(&self, ops: &mut ::malloc_size_of::MallocSizeOfOps) -> usize { > let mut sum = 0; >@@ -68,28 +81,33 @@ fn malloc_size_of_derive(s: synstructure::Structure) -> quote::Tokens { > } > }; > > tokens > } > > #[test] > fn test_struct() { >- let source = >- syn::parse_str("struct Foo<T> { bar: Bar, baz: T, #[ignore_malloc_size_of = \"\"] z: Arc<T> }").unwrap(); >+ let source = syn::parse_str( >+ "struct Foo<T> { bar: Bar, baz: T, #[ignore_malloc_size_of = \"\"] z: Arc<T> }", >+ ).unwrap(); > let source = synstructure::Structure::new(&source); > > let expanded = malloc_size_of_derive(source).to_string(); > let mut no_space = expanded.replace(" ", ""); > macro_rules! match_count { > ($e: expr, $count: expr) => { >- assert_eq!(no_space.matches(&$e.replace(" ", "")).count(), $count, >- "counting occurences of {:?} in {:?} (whitespace-insensitive)", >- $e, expanded) >- } >+ assert_eq!( >+ no_space.matches(&$e.replace(" ", "")).count(), >+ $count, >+ "counting occurences of {:?} in {:?} (whitespace-insensitive)", >+ $e, >+ expanded >+ ) >+ }; > } > match_count!("struct", 0); > match_count!("ignore_malloc_size_of", 0); > match_count!("impl<T> ::malloc_size_of::MallocSizeOf for Foo<T> where T: ::malloc_size_of::MallocSizeOf {", 1); > match_count!("sum += ::malloc_size_of::MallocSizeOf::size_of(", 2); > > let source = syn::parse_str("struct Bar([Baz; 3]);").unwrap(); > let source = synstructure::Structure::new(&source); >@@ -99,9 +117,8 @@ fn test_struct() { > } > > #[should_panic(expected = "should have an explanation")] > #[test] > fn test_no_reason() { > let input = syn::parse_str("struct A { #[ignore_malloc_size_of] b: C }").unwrap(); > malloc_size_of_derive(synstructure::Structure::new(&input)); > } >- >diff --git a/servo/components/selectors/attr.rs b/servo/components/selectors/attr.rs >index c0f5fe731859..ce0aa64344cf 100644 >--- a/servo/components/selectors/attr.rs >+++ b/servo/components/selectors/attr.rs >@@ -110,26 +110,26 @@ impl AttrSelectorOperator { > let e = element_attr_value.as_bytes(); > let s = attr_selector_value.as_bytes(); > let case = case_sensitivity; > match self { > AttrSelectorOperator::Equal => case.eq(e, s), > AttrSelectorOperator::Prefix => e.len() >= s.len() && case.eq(&e[..s.len()], s), > AttrSelectorOperator::Suffix => { > e.len() >= s.len() && case.eq(&e[(e.len() - s.len())..], s) >- }, >+ } > AttrSelectorOperator::Substring => { > case.contains(element_attr_value, attr_selector_value) >- }, >+ } > AttrSelectorOperator::Includes => element_attr_value > .split(SELECTOR_WHITESPACE) > .any(|part| case.eq(part.as_bytes(), s)), > AttrSelectorOperator::DashMatch => { > case.eq(e, s) || (e.get(s.len()) == Some(&b'-') && case.eq(&e[..s.len()], s)) >- }, >+ } > } > } > } > > /// The definition of whitespace per CSS Selectors Level 3 § 4. > pub static SELECTOR_WHITESPACE: &'static [char] = &[' ', '\t', '\n', '\r', '\x0C']; > > #[derive(Clone, Copy, Debug, Eq, PartialEq)] >@@ -141,20 +141,20 @@ pub enum ParsedCaseSensitivity { > > impl ParsedCaseSensitivity { > pub fn to_unconditional(self, is_html_element_in_html_document: bool) -> CaseSensitivity { > match self { > ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument > if is_html_element_in_html_document => > { > CaseSensitivity::AsciiCaseInsensitive >- }, >+ } > ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => { > CaseSensitivity::CaseSensitive >- }, >+ } > ParsedCaseSensitivity::CaseSensitive => CaseSensitivity::CaseSensitive, > ParsedCaseSensitivity::AsciiCaseInsensitive => CaseSensitivity::AsciiCaseInsensitive, > } > } > } > > #[derive(Clone, Copy, Debug, Eq, PartialEq)] > pub enum CaseSensitivity { >@@ -185,12 +185,12 @@ impl CaseSensitivity { > Some(haystack_slice) => haystack_slice.eq_ignore_ascii_case(n_rest), > } > }) > } else { > // any_str.contains("") == true, > // though these cases should be handled with *NeverMatches and never go here. > true > } >- }, >+ } > } > } > } >diff --git a/servo/components/selectors/bloom.rs b/servo/components/selectors/bloom.rs >index d9056665ac4d..f868fc7df165 100644 >--- a/servo/components/selectors/bloom.rs >+++ b/servo/components/selectors/bloom.rs >@@ -313,30 +313,33 @@ fn create_and_insert_some_stuff() { > for i in 0_usize..1000 { > bf.insert_hash(hash_as_str(i)); > } > > for i in 0_usize..1000 { > assert!(bf.might_contain_hash(hash_as_str(i))); > } > >- let false_positives = >- (1001_usize..2000).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count(); >+ let false_positives = (1001_usize..2000) >+ .filter(|i| bf.might_contain_hash(hash_as_str(*i))) >+ .count(); > > assert!(false_positives < 190, "{} is not < 190", false_positives); // 19%. > > for i in 0_usize..100 { > bf.remove_hash(hash_as_str(i)); > } > > for i in 100_usize..1000 { > assert!(bf.might_contain_hash(hash_as_str(i))); > } > >- let false_positives = (0_usize..100).filter(|i| bf.might_contain_hash(hash_as_str(*i))).count(); >+ let false_positives = (0_usize..100) >+ .filter(|i| bf.might_contain_hash(hash_as_str(*i))) >+ .count(); > > assert!(false_positives < 20, "{} is not < 20", false_positives); // 20%. > > bf.clear(); > > for i in 0_usize..2000 { > assert!(!bf.might_contain_hash(hash_as_str(i))); > } >diff --git a/servo/components/selectors/builder.rs b/servo/components/selectors/builder.rs >index 29ac822fa033..c6a3bb350540 100644 >--- a/servo/components/selectors/builder.rs >+++ b/servo/components/selectors/builder.rs >@@ -18,17 +18,17 @@ > //! easy-to-use API for the parser. > > use parser::{Combinator, Component, SelectorImpl}; > use servo_arc::{Arc, HeaderWithLength, ThinArc}; > use sink::Push; > use smallvec::{self, SmallVec}; > use std::cmp; > use std::iter; >-use std::ops::{AddAssign, Add}; >+use std::ops::{Add, AddAssign}; > use std::ptr; > use std::slice; > > /// Top-level SelectorBuilder struct. This should be stack-allocated by the > /// consumer and never moved (because it contains a lot of inline data that > /// would be slow to memmov). > /// > /// After instantation, callers may call the push_simple_selector() and >@@ -156,18 +156,19 @@ impl<Impl: SelectorImpl> SelectorBuilder<Impl> { > struct SelectorBuilderIter<'a, Impl: SelectorImpl> { > current_simple_selectors: slice::Iter<'a, Component<Impl>>, > rest_of_simple_selectors: &'a [Component<Impl>], > combinators: iter::Rev<smallvec::Drain<'a, (Combinator, usize)>>, > } > > impl<'a, Impl: SelectorImpl> ExactSizeIterator for SelectorBuilderIter<'a, Impl> { > fn len(&self) -> usize { >- self.current_simple_selectors.len() + self.rest_of_simple_selectors.len() + >- self.combinators.len() >+ self.current_simple_selectors.len() >+ + self.rest_of_simple_selectors.len() >+ + self.combinators.len() > } > } > > impl<'a, Impl: SelectorImpl> Iterator for SelectorBuilderIter<'a, Impl> { > type Item = Component<Impl>; > #[inline(always)] > fn next(&mut self) -> Option<Self::Item> { > if let Some(simple_selector_ref) = self.current_simple_selectors.next() { >@@ -223,17 +224,16 @@ const MAX_10BIT: u32 = (1u32 << 10) - 1; > > #[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)] > struct Specificity { > id_selectors: u32, > class_like_selectors: u32, > element_selectors: u32, > } > >- > impl AddAssign for Specificity { > #[inline] > fn add_assign(&mut self, rhs: Self) { > self.id_selectors += rhs.id_selectors; > self.class_like_selectors += rhs.class_like_selectors; > self.element_selectors += rhs.element_selectors; > } > } >@@ -270,19 +270,19 @@ impl From<u32> for Specificity { > element_selectors: value & MAX_10BIT, > } > } > } > > impl From<Specificity> for u32 { > #[inline] > fn from(specificity: Specificity) -> u32 { >- cmp::min(specificity.id_selectors, MAX_10BIT) << 20 | >- cmp::min(specificity.class_like_selectors, MAX_10BIT) << 10 | >- cmp::min(specificity.element_selectors, MAX_10BIT) >+ cmp::min(specificity.id_selectors, MAX_10BIT) << 20 >+ | cmp::min(specificity.class_like_selectors, MAX_10BIT) << 10 >+ | cmp::min(specificity.element_selectors, MAX_10BIT) > } > } > > fn specificity<Impl>(builder: &SelectorBuilder<Impl>, iter: slice::Iter<Component<Impl>>) -> u32 > where > Impl: SelectorImpl, > { > complex_selector_specificity(builder, iter).into() >@@ -301,75 +301,74 @@ where > specificity: &mut Specificity, > ) where > Impl: SelectorImpl, > { > match *simple_selector { > Component::Combinator(ref combinator) => { > unreachable!( > "Found combinator {:?} in simple selectors vector? {:?}", >- combinator, >- builder, >+ combinator, builder, > ); > } > Component::PseudoElement(..) | Component::LocalName(..) => { > specificity.element_selectors += 1 >- }, >+ } > Component::Slotted(ref selector) => { > specificity.element_selectors += 1; > // Note that due to the way ::slotted works we only compete with > // other ::slotted rules, so the above rule doesn't really > // matter, but we do it still for consistency with other > // pseudo-elements. > // > // See: https://github.com/w3c/csswg-drafts/issues/1915 > *specificity += Specificity::from(selector.specificity()); >- }, >+ } > Component::Host(ref selector) => { > specificity.class_like_selectors += 1; > if let Some(ref selector) = *selector { > // See: https://github.com/w3c/csswg-drafts/issues/1915 > *specificity += Specificity::from(selector.specificity()); > } > } > Component::ID(..) => { > specificity.id_selectors += 1; >- }, >- Component::Class(..) | >- Component::AttributeInNoNamespace { .. } | >- Component::AttributeInNoNamespaceExists { .. } | >- Component::AttributeOther(..) | >- Component::FirstChild | >- Component::LastChild | >- Component::OnlyChild | >- Component::Root | >- Component::Empty | >- Component::Scope | >- Component::NthChild(..) | >- Component::NthLastChild(..) | >- Component::NthOfType(..) | >- Component::NthLastOfType(..) | >- Component::FirstOfType | >- Component::LastOfType | >- Component::OnlyOfType | >- Component::NonTSPseudoClass(..) => { >+ } >+ Component::Class(..) >+ | Component::AttributeInNoNamespace { .. } >+ | Component::AttributeInNoNamespaceExists { .. } >+ | Component::AttributeOther(..) >+ | Component::FirstChild >+ | Component::LastChild >+ | Component::OnlyChild >+ | Component::Root >+ | Component::Empty >+ | Component::Scope >+ | Component::NthChild(..) >+ | Component::NthLastChild(..) >+ | Component::NthOfType(..) >+ | Component::NthLastOfType(..) >+ | Component::FirstOfType >+ | Component::LastOfType >+ | Component::OnlyOfType >+ | Component::NonTSPseudoClass(..) => { > specificity.class_like_selectors += 1; >- }, >- Component::ExplicitUniversalType | >- Component::ExplicitAnyNamespace | >- Component::ExplicitNoNamespace | >- Component::DefaultNamespace(..) | >- Component::Namespace(..) => { >+ } >+ Component::ExplicitUniversalType >+ | Component::ExplicitAnyNamespace >+ | Component::ExplicitNoNamespace >+ | Component::DefaultNamespace(..) >+ | Component::Namespace(..) => { > // Does not affect specificity >- }, >+ } > Component::Negation(ref negated) => { > for ss in negated.iter() { > simple_selector_specificity(builder, &ss, specificity); > } >- }, >+ } > } > } > > let mut specificity = Default::default(); > for simple_selector in &mut iter { > simple_selector_specificity(builder, &simple_selector, &mut specificity); > } > specificity >diff --git a/servo/components/selectors/context.rs b/servo/components/selectors/context.rs >index 9d1bfeee346d..f0ac93caa9eb 100644 >--- a/servo/components/selectors/context.rs >+++ b/servo/components/selectors/context.rs >@@ -48,27 +48,27 @@ pub enum VisitedHandlingMode { > RelevantLinkVisited, > } > > impl VisitedHandlingMode { > #[inline] > pub fn matches_visited(&self) -> bool { > matches!( > *self, >- VisitedHandlingMode::RelevantLinkVisited | >- VisitedHandlingMode::AllLinksVisitedAndUnvisited >+ VisitedHandlingMode::RelevantLinkVisited >+ | VisitedHandlingMode::AllLinksVisitedAndUnvisited > ) > } > > #[inline] > pub fn matches_unvisited(&self) -> bool { > matches!( > *self, >- VisitedHandlingMode::AllLinksUnvisited | >- VisitedHandlingMode::AllLinksVisitedAndUnvisited >+ VisitedHandlingMode::AllLinksUnvisited >+ | VisitedHandlingMode::AllLinksVisitedAndUnvisited > ) > } > } > > /// Which quirks mode is this document in. > /// > /// See: https://quirks.spec.whatwg.org/ > #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] >diff --git a/servo/components/selectors/matching.rs b/servo/components/selectors/matching.rs >index 1fe54b217d23..5e643752ada8 100644 >--- a/servo/components/selectors/matching.rs >+++ b/servo/components/selectors/matching.rs >@@ -46,19 +46,19 @@ bitflags! { > impl ElementSelectorFlags { > /// Returns the subset of flags that apply to the element. > pub fn for_self(self) -> ElementSelectorFlags { > self & (ElementSelectorFlags::HAS_EMPTY_SELECTOR) > } > > /// Returns the subset of flags that apply to the parent. > pub fn for_parent(self) -> ElementSelectorFlags { >- self & (ElementSelectorFlags::HAS_SLOW_SELECTOR | >- ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS | >- ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR) >+ self & (ElementSelectorFlags::HAS_SLOW_SELECTOR >+ | ElementSelectorFlags::HAS_SLOW_SELECTOR_LATER_SIBLINGS >+ | ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR) > } > } > > /// Holds per-compound-selector data. > struct LocalMatchingContext<'a, 'b: 'a, Impl: SelectorImpl> { > shared: &'a mut MatchingContext<'b, Impl>, > matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk, > } >@@ -255,22 +255,21 @@ where > from_offset += 1; > } > > debug_assert!(from_offset >= 1); > debug_assert!(from_offset <= selector.len()); > > let iter = selector.iter_from(selector.len() - from_offset); > debug_assert!( >- iter.clone().next().is_some() || >- (from_offset != selector.len() && >- matches!( >- selector.combinator_at_parse_order(from_offset), >- Combinator::SlotAssignment | Combinator::PseudoElement >- )), >+ iter.clone().next().is_some() >+ || (from_offset != selector.len() && matches!( >+ selector.combinator_at_parse_order(from_offset), >+ Combinator::SlotAssignment | Combinator::PseudoElement >+ )), > "Got the math wrong: {:?} | {:?} | {} {}", > selector, > selector.iter_raw_match_order().as_slice(), > from_offset, > start_offset > ); > > for component in iter { >@@ -306,24 +305,24 @@ where > // Consume the pseudo. > match *iter.next().unwrap() { > Component::PseudoElement(ref pseudo) => { > if let Some(ref f) = context.pseudo_element_matching_fn { > if !f(pseudo) { > return false; > } > } >- }, >+ } > _ => { > debug_assert!( > false, > "Used MatchingMode::ForStatelessPseudoElement \ > in a non-pseudo selector" > ); >- }, >+ } > } > > // The only other parser-allowed Component in this sequence is a state > // class. We just don't match in that case. > if let Some(s) = iter.next() { > debug_assert!( > matches!(*s, Component::NonTSPseudoClass(..)), > "Someone messed up pseudo-element parsing" >@@ -358,42 +357,42 @@ fn matches_hover_and_active_quirk<Impl: SelectorImpl>( > } > > if context.is_nested() { > return MatchesHoverAndActiveQuirk::No; > } > > // This compound selector had a pseudo-element to the right that we > // intentionally skipped. >- if rightmost == Rightmost::Yes && >- context.matching_mode() == MatchingMode::ForStatelessPseudoElement >+ if rightmost == Rightmost::Yes >+ && context.matching_mode() == MatchingMode::ForStatelessPseudoElement > { > return MatchesHoverAndActiveQuirk::No; > } > > let all_match = selector_iter.clone().all(|simple| match *simple { >- Component::LocalName(_) | >- Component::AttributeInNoNamespaceExists { .. } | >- Component::AttributeInNoNamespace { .. } | >- Component::AttributeOther(_) | >- Component::ID(_) | >- Component::Class(_) | >- Component::PseudoElement(_) | >- Component::Negation(_) | >- Component::FirstChild | >- Component::LastChild | >- Component::OnlyChild | >- Component::Empty | >- Component::NthChild(_, _) | >- Component::NthLastChild(_, _) | >- Component::NthOfType(_, _) | >- Component::NthLastOfType(_, _) | >- Component::FirstOfType | >- Component::LastOfType | >- Component::OnlyOfType => false, >+ Component::LocalName(_) >+ | Component::AttributeInNoNamespaceExists { .. } >+ | Component::AttributeInNoNamespace { .. } >+ | Component::AttributeOther(_) >+ | Component::ID(_) >+ | Component::Class(_) >+ | Component::PseudoElement(_) >+ | Component::Negation(_) >+ | Component::FirstChild >+ | Component::LastChild >+ | Component::OnlyChild >+ | Component::Empty >+ | Component::NthChild(_, _) >+ | Component::NthLastChild(_, _) >+ | Component::NthOfType(_, _) >+ | Component::NthLastOfType(_, _) >+ | Component::FirstOfType >+ | Component::LastOfType >+ | Component::OnlyOfType => false, > Component::NonTSPseudoClass(ref pseudo_class) => pseudo_class.is_active_or_hover(), > _ => true, > }); > > if all_match { > MatchesHoverAndActiveQuirk::Yes > } else { > MatchesHoverAndActiveQuirk::No >@@ -415,17 +414,17 @@ fn next_element_for_combinator<E>( > where > E: Element, > { > match combinator { > Combinator::NextSibling | Combinator::LaterSibling => element.prev_sibling_element(), > Combinator::Child | Combinator::Descendant => { > match element.parent_element() { > Some(e) => return Some(e), >- None => {}, >+ None => {} > } > > if !element.parent_node_is_shadow_root() { > return None; > } > > // https://drafts.csswg.org/css-scoping/#host-element-in-tree: > // >@@ -443,25 +442,25 @@ where > // Since we know that the parent is a shadow root, we necessarily > // are in a shadow tree of the host, and the next selector will only > // match if the selector is a featureless :host selector. > if !selector.clone().is_featureless_host_selector() { > return None; > } > > element.containing_shadow_host() >- }, >+ } > Combinator::SlotAssignment => { > debug_assert!( > element > .assigned_slot() > .map_or(true, |s| s.is_html_slot_element()) > ); > element.assigned_slot() >- }, >+ } > Combinator::PseudoElement => element.pseudo_element_originating_element(), > } > } > > fn matches_complex_selector_internal<E, F>( > mut selector_iter: SelectorIter<E::Impl>, > element: &E, > context: &mut MatchingContext<E::Impl>, >@@ -500,21 +499,21 @@ where > let combinator = match combinator { > None => return SelectorMatchingResult::Matched, > Some(c) => c, > }; > > let candidate_not_found = match combinator { > Combinator::NextSibling | Combinator::LaterSibling => { > SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant >- }, >- Combinator::Child | >- Combinator::Descendant | >- Combinator::SlotAssignment | >- Combinator::PseudoElement => SelectorMatchingResult::NotMatchedGlobally, >+ } >+ Combinator::Child >+ | Combinator::Descendant >+ | Combinator::SlotAssignment >+ | Combinator::PseudoElement => SelectorMatchingResult::NotMatchedGlobally, > }; > > let mut next_element = next_element_for_combinator(element, combinator, &selector_iter); > > // Stop matching :visited as soon as we find a link, or a combinator for > // something that isn't an ancestor. > let mut visited_handling = if element.is_link() || combinator.is_sibling() { > VisitedHandlingMode::AllLinksUnvisited >@@ -535,46 +534,46 @@ where > context, > flags_setter, > Rightmost::No, > ) > }); > > match (result, combinator) { > // Return the status immediately. >- (SelectorMatchingResult::Matched, _) | >- (SelectorMatchingResult::NotMatchedGlobally, _) | >- (_, Combinator::NextSibling) => { >+ (SelectorMatchingResult::Matched, _) >+ | (SelectorMatchingResult::NotMatchedGlobally, _) >+ | (_, Combinator::NextSibling) => { > return result; >- }, >+ } > > // Upgrade the failure status to > // NotMatchedAndRestartFromClosestDescendant. > (_, Combinator::PseudoElement) | (_, Combinator::Child) => { > return SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant; >- }, >+ } > > // If the failure status is > // NotMatchedAndRestartFromClosestDescendant and combinator is > // Combinator::LaterSibling, give up this Combinator::LaterSibling > // matching and restart from the closest descendant combinator. > ( > SelectorMatchingResult::NotMatchedAndRestartFromClosestDescendant, > Combinator::LaterSibling, > ) => { > return result; >- }, >+ } > > // The Combinator::Descendant combinator and the status is > // NotMatchedAndRestartFromClosestLaterSibling or > // NotMatchedAndRestartFromClosestDescendant, or the > // Combinator::LaterSibling combinator and the status is > // NotMatchedAndRestartFromClosestDescendant, we can continue to > // matching on the next candidate element. >- _ => {}, >+ _ => {} > } > > if element.is_link() { > visited_handling = VisitedHandlingMode::AllLinksUnvisited; > } > > next_element = next_element_for_combinator(&element, combinator, &selector_iter); > } >@@ -658,50 +657,51 @@ where > F: FnMut(&E, ElementSelectorFlags), > { > debug_assert!(context.shared.is_nested() || !context.shared.in_negation()); > > match *selector { > Component::Combinator(_) => unreachable!(), > Component::Slotted(ref selector) => { > // <slots> are never flattened tree slottables. >- !element.is_html_slot_element() && element.assigned_slot().is_some() && >- context.shared.nest(|context| { >+ !element.is_html_slot_element() && element.assigned_slot().is_some() && context >+ .shared >+ .nest(|context| { > matches_complex_selector(selector.iter(), element, context, flags_setter) > }) >- }, >+ } > Component::PseudoElement(ref pseudo) => { > element.match_pseudo_element(pseudo, context.shared) >- }, >+ } > Component::LocalName(ref local_name) => matches_local_name(element, local_name), > Component::ExplicitUniversalType | Component::ExplicitAnyNamespace => true, > Component::Namespace(_, ref url) | Component::DefaultNamespace(ref url) => { > element.namespace() == url.borrow() >- }, >+ } > Component::ExplicitNoNamespace => { > let ns = ::parser::namespace_empty_string::<E::Impl>(); > element.namespace() == ns.borrow() >- }, >+ } > Component::ID(ref id) => { > element.has_id(id, context.shared.classes_and_ids_case_sensitivity()) >- }, >+ } > Component::Class(ref class) => { > element.has_class(class, context.shared.classes_and_ids_case_sensitivity()) >- }, >+ } > Component::AttributeInNoNamespaceExists { > ref local_name, > ref local_name_lower, > } => { > let is_html = element.is_html_element_in_html_document(); > element.attr_matches( > &NamespaceConstraint::Specific(&::parser::namespace_empty_string::<E::Impl>()), > select_name(is_html, local_name, local_name_lower), > &AttrSelectorOperation::Exists, > ) >- }, >+ } > Component::AttributeInNoNamespace { > ref local_name, > ref value, > operator, > case_sensitivity, > never_matches, > } => { > if never_matches { >@@ -712,17 +712,17 @@ where > &NamespaceConstraint::Specific(&::parser::namespace_empty_string::<E::Impl>()), > local_name, > &AttrSelectorOperation::WithValue { > operator: operator, > case_sensitivity: case_sensitivity.to_unconditional(is_html), > expected_value: value, > }, > ) >- }, >+ } > Component::AttributeOther(ref attr_sel) => { > if attr_sel.never_matches { > return false; > } > let is_html = element.is_html_element_in_html_document(); > let empty_string; > let namespace = match attr_sel.namespace() { > Some(ns) => ns, >@@ -742,74 +742,75 @@ where > ref expected_value, > } => AttrSelectorOperation::WithValue { > operator: operator, > case_sensitivity: case_sensitivity.to_unconditional(is_html), > expected_value: expected_value, > }, > }, > ) >- }, >+ } > Component::NonTSPseudoClass(ref pc) => { >- if context.matches_hover_and_active_quirk == MatchesHoverAndActiveQuirk::Yes && >- !context.shared.is_nested() && pc.is_active_or_hover() && >- !element.is_link() >+ if context.matches_hover_and_active_quirk == MatchesHoverAndActiveQuirk::Yes >+ && !context.shared.is_nested() >+ && pc.is_active_or_hover() >+ && !element.is_link() > { > return false; > } > > element.match_non_ts_pseudo_class(pc, &mut context.shared, flags_setter) >- }, >+ } > Component::FirstChild => matches_first_child(element, flags_setter), > Component::LastChild => matches_last_child(element, flags_setter), > Component::OnlyChild => { > matches_first_child(element, flags_setter) && matches_last_child(element, flags_setter) >- }, >+ } > Component::Root => element.is_root(), > Component::Empty => { > flags_setter(element, ElementSelectorFlags::HAS_EMPTY_SELECTOR); > element.is_empty() >- }, >+ } > Component::Host(ref selector) => { > context > .shared > .shadow_host() >- .map_or(false, |host| host == element.opaque()) && >- selector.as_ref().map_or(true, |selector| { >+ .map_or(false, |host| host == element.opaque()) >+ && selector.as_ref().map_or(true, |selector| { > context.shared.nest(|context| { > matches_complex_selector(selector.iter(), element, context, flags_setter) > }) > }) >- }, >+ } > Component::Scope => match context.shared.scope_element { > Some(ref scope_element) => element.opaque() == *scope_element, > None => element.is_root(), > }, > Component::NthChild(a, b) => { > matches_generic_nth_child(element, context, a, b, false, false, flags_setter) >- }, >+ } > Component::NthLastChild(a, b) => { > matches_generic_nth_child(element, context, a, b, false, true, flags_setter) >- }, >+ } > Component::NthOfType(a, b) => { > matches_generic_nth_child(element, context, a, b, true, false, flags_setter) >- }, >+ } > Component::NthLastOfType(a, b) => { > matches_generic_nth_child(element, context, a, b, true, true, flags_setter) >- }, >+ } > Component::FirstOfType => { > matches_generic_nth_child(element, context, 0, 1, true, false, flags_setter) >- }, >+ } > Component::LastOfType => { > matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter) >- }, >+ } > Component::OnlyOfType => { >- matches_generic_nth_child(element, context, 0, 1, true, false, flags_setter) && >- matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter) >- }, >+ matches_generic_nth_child(element, context, 0, 1, true, false, flags_setter) >+ && matches_generic_nth_child(element, context, 0, 1, true, true, flags_setter) >+ } > Component::Negation(ref negated) => context.shared.nest_for_negation(|context| { > let mut local_context = LocalMatchingContext { > matches_hover_and_active_quirk: MatchesHoverAndActiveQuirk::No, > shared: context, > }; > !negated > .iter() > .all(|ss| matches_simple_selector(ss, element, &mut local_context, flags_setter)) >diff --git a/servo/components/selectors/parser.rs b/servo/components/selectors/parser.rs >index d0f98cde57bb..5b2d0c746604 100644 >--- a/servo/components/selectors/parser.rs >+++ b/servo/components/selectors/parser.rs >@@ -3,20 +3,20 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > use attr::{AttrSelectorOperator, AttrSelectorWithOptionalNamespace}; > use attr::{NamespaceConstraint, ParsedAttrSelectorOperation}; > use attr::{ParsedCaseSensitivity, SELECTOR_WHITESPACE}; > use bloom::BLOOM_HASH_MASK; > use builder::{SelectorBuilder, SpecificityAndFlags}; > use context::QuirksMode; >+use cssparser::{parse_nth, serialize_identifier}; > use cssparser::{BasicParseError, BasicParseErrorKind, ParseError, ParseErrorKind}; > use cssparser::{CowRcStr, Delimiter, SourceLocation}; > use cssparser::{CssStringWriter, Parser as CssParser, ToCss, Token}; >-use cssparser::{parse_nth, serialize_identifier}; > use precomputed_hash::PrecomputedHash; > use servo_arc::ThinArc; > use sink::Push; > use smallvec::SmallVec; > use std::borrow::{Borrow, Cow}; > use std::fmt::{self, Debug, Display, Write}; > use std::iter::Rev; > use std::slice; >@@ -226,19 +226,20 @@ impl<Impl: SelectorImpl> SelectorList<Impl> { > parser: &P, > input: &mut CssParser<'i, 't>, > ) -> Result<Self, ParseError<'i, P::Error>> > where > P: Parser<'i, Impl = Impl>, > { > let mut values = SmallVec::new(); > loop { >- values >- .push(input >- .parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?); >+ values.push( >+ input >+ .parse_until_before(Delimiter::Comma, |input| parse_selector(parser, input))?, >+ ); > match input.next() { > Err(_) => return Ok(SelectorList(values)), > Ok(&Token::Comma) => continue, > Ok(_) => unreachable!(), > } > } > } > >@@ -340,19 +341,19 @@ impl AncestorHashes { > > AncestorHashes { > packed_hashes: [hashes[0], hashes[1], hashes[2]], > } > } > > /// Returns the fourth hash, reassembled from parts. > pub fn fourth_hash(&self) -> u32 { >- ((self.packed_hashes[0] & 0xff000000) >> 24) | >- ((self.packed_hashes[1] & 0xff000000) >> 16) | >- ((self.packed_hashes[2] & 0xff000000) >> 8) >+ ((self.packed_hashes[0] & 0xff000000) >> 24) >+ | ((self.packed_hashes[1] & 0xff000000) >> 16) >+ | ((self.packed_hashes[2] & 0xff000000) >> 8) > } > } > > impl<Impl: SelectorImpl> Visit for Selector<Impl> > where > Impl::NonTSPseudoClass: Visit<Impl = Impl>, > { > type Impl = Impl; >@@ -399,80 +400,81 @@ where > return false; > } > > match *self { > Slotted(ref selector) => { > if !selector.visit(visitor) { > return false; > } >- }, >+ } > Host(Some(ref selector)) => { > if !selector.visit(visitor) { > return false; > } >- }, >+ } > Negation(ref negated) => { > for component in negated.iter() { > if !component.visit(visitor) { > return false; > } > } >- }, >+ } > > AttributeInNoNamespaceExists { > ref local_name, > ref local_name_lower, > } => { > if !visitor.visit_attribute_selector( > &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()), > local_name, > local_name_lower, > ) { > return false; > } >- }, >+ } > AttributeInNoNamespace { > ref local_name, > never_matches, > .. >- } if !never_matches => >+ } >+ if !never_matches => > { > if !visitor.visit_attribute_selector( > &NamespaceConstraint::Specific(&namespace_empty_string::<Impl>()), > local_name, > local_name, > ) { > return false; > } >- }, >+ } > AttributeOther(ref attr_selector) if !attr_selector.never_matches => { > let empty_string; > let namespace = match attr_selector.namespace() { > Some(ns) => ns, > None => { > empty_string = ::parser::namespace_empty_string::<Impl>(); > NamespaceConstraint::Specific(&empty_string) > } > }; > if !visitor.visit_attribute_selector( > &namespace, > &attr_selector.local_name, > &attr_selector.local_name_lower, > ) { > return false; > } >- }, >+ } > > NonTSPseudoClass(ref pseudo_class) => { > if !pseudo_class.visit(visitor) { > return false; > } >- }, >- _ => {}, >+ } >+ _ => {} > } > > true > } > } > > pub fn namespace_empty_string<Impl: SelectorImpl>() -> Impl::NamespaceUrl { > // Rust typeâs default, not default namespace >@@ -531,19 +533,20 @@ impl<Impl: SelectorImpl> Selector<Impl> { > /// Whether this selector (pseudo-element part excluded) matches every element. > /// > /// Used for "pre-computed" pseudo-elements in components/style/stylist.rs > #[inline] > pub fn is_universal(&self) -> bool { > self.iter_raw_match_order().all(|c| { > matches!( > *c, >- Component::ExplicitUniversalType | Component::ExplicitAnyNamespace | >- Component::Combinator(Combinator::PseudoElement) | >- Component::PseudoElement(..) >+ Component::ExplicitUniversalType >+ | Component::ExplicitAnyNamespace >+ | Component::Combinator(Combinator::PseudoElement) >+ | Component::PseudoElement(..) > ) > }) > } > > /// Returns an iterator over this selector in matching order (right-to-left). > /// When a combinator is reached, the iterator will return None, and > /// next_sequence() may be called to continue to the next sequence. > #[inline] >@@ -560,17 +563,17 @@ impl<Impl: SelectorImpl> Selector<Impl> { > #[inline] > pub fn is_featureless_host_selector_or_pseudo_element(&self) -> bool { > let mut iter = self.iter(); > if !self.has_pseudo_element() { > return iter.is_featureless_host_selector(); > } > > // Skip the pseudo-element. >- for _ in &mut iter { } >+ for _ in &mut iter {} > > match iter.next_sequence() { > None => return false, > Some(combinator) => { > debug_assert_eq!(combinator, Combinator::PseudoElement); > } > } > >@@ -668,18 +671,18 @@ impl<'a, Impl: 'a + SelectorImpl> SelectorIter<'a, Impl> { > pub fn next_sequence(&mut self) -> Option<Combinator> { > self.next_combinator.take() > } > > /// Whether this selector is a featureless host selector, with no > /// combinators to the left. > #[inline] > pub(crate) fn is_featureless_host_selector(&mut self) -> bool { >- self.all(|component| matches!(*component, Component::Host(..))) && >- self.next_sequence().is_none() >+ self.all(|component| matches!(*component, Component::Host(..))) >+ && self.next_sequence().is_none() > } > > /// Returns remaining count of the simple selectors and combinators in the Selector. > #[inline] > pub fn selector_length(&self) -> usize { > self.iter.len() > } > } >@@ -692,17 +695,17 @@ impl<'a, Impl: SelectorImpl> Iterator for SelectorIter<'a, Impl> { > debug_assert!( > self.next_combinator.is_none(), > "You should call next_sequence!" > ); > match *self.iter.next()? { > Component::Combinator(c) => { > self.next_combinator = Some(c); > None >- }, >+ } > ref x => Some(x), > } > } > } > > impl<'a, Impl: SelectorImpl> fmt::Debug for SelectorIter<'a, Impl> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > let iter = self.iter.clone().rev(); >@@ -780,18 +783,20 @@ pub enum Combinator { > } > > impl Combinator { > /// Returns true if this combinator is a child or descendant combinator. > #[inline] > pub fn is_ancestor(&self) -> bool { > matches!( > *self, >- Combinator::Child | Combinator::Descendant | Combinator::PseudoElement | >- Combinator::SlotAssignment >+ Combinator::Child >+ | Combinator::Descendant >+ | Combinator::PseudoElement >+ | Combinator::SlotAssignment > ) > } > > /// Returns true if this combinator is a pseudo-element combinator. > #[inline] > pub fn is_pseudo_element(&self) -> bool { > matches!(*self, Combinator::PseudoElement) > } >@@ -905,28 +910,28 @@ impl<Impl: SelectorImpl> Component<Impl> { > // Only insert the local-name into the filter if it's all > // lowercase. Otherwise we would need to test both hashes, and > // our data structures aren't really set up for that. > if name == lower_name { > Some(name.precomputed_hash()) > } else { > None > } >- }, >+ } > Component::DefaultNamespace(ref url) | Component::Namespace(_, ref url) => { > Some(url.precomputed_hash()) >- }, >+ } > // In quirks mode, class and id selectors should match > // case-insensitively, so just avoid inserting them into the filter. > Component::ID(ref id) if quirks_mode != QuirksMode::Quirks => { > Some(id.precomputed_hash()) >- }, >+ } > Component::Class(ref class) if quirks_mode != QuirksMode::Quirks => { > Some(class.precomputed_hash()) >- }, >+ } > _ => None, > } > } > > /// Returns true if this is a combinator. > pub fn is_combinator(&self) -> bool { > matches!(*self, Component::Combinator(_)) > } >@@ -971,17 +976,18 @@ impl<Impl: SelectorImpl> Debug for LocalName<Impl> { > } > > impl<Impl: SelectorImpl> ToCss for SelectorList<Impl> { > fn to_css<W>(&self, dest: &mut W) -> fmt::Result > where > W: fmt::Write, > { > let mut iter = self.0.iter(); >- let first = iter.next() >+ let first = iter >+ .next() > .expect("Empty SelectorList, should contain at least one selector"); > first.to_css(dest)?; > for selector in iter { > dest.write_str(", ")?; > selector.to_css(dest)?; > } > Ok(()) > } >@@ -999,20 +1005,22 @@ impl<Impl: SelectorImpl> ToCss for Selector<Impl> { > // We could do something more clever, but selector serialization probably > // isn't hot enough to justify it, and the stringification likely > // dominates anyway. > // > // NB: A parse-order iterator is a Rev<>, which doesn't expose as_slice(), > // which we need for |split|. So we split by combinators on a match-order > // sequence and then reverse. > >- let mut combinators = self.iter_raw_match_order() >+ let mut combinators = self >+ .iter_raw_match_order() > .rev() > .filter_map(|x| x.as_combinator()); >- let compound_selectors = self.iter_raw_match_order() >+ let compound_selectors = self >+ .iter_raw_match_order() > .as_slice() > .split(|x| x.is_combinator()) > .rev(); > > let mut combinators_exhausted = false; > for compound in compound_selectors { > debug_assert!(!combinators_exhausted); > >@@ -1027,44 +1035,44 @@ impl<Impl: SelectorImpl> ToCss for Selector<Impl> { > // > // Check if `!compound.empty()` first--this can happen if we have > // something like `... > ::before`, because we store `>` and `::` > // both as combinators internally. > // > // If we are in this case, after we have serialized the universal > // selector, we skip Step 2 and continue with the algorithm. > let (can_elide_namespace, first_non_namespace) = match compound[0] { >- Component::ExplicitAnyNamespace | >- Component::ExplicitNoNamespace | >- Component::Namespace(..) => (false, 1), >+ Component::ExplicitAnyNamespace >+ | Component::ExplicitNoNamespace >+ | Component::Namespace(..) => (false, 1), > Component::DefaultNamespace(..) => (true, 1), > _ => (true, 0), > }; > let mut perform_step_2 = true; > let next_combinator = combinators.next(); > if first_non_namespace == compound.len() - 1 { > match (next_combinator, &compound[first_non_namespace]) { > // We have to be careful here, because if there is a > // pseudo element "combinator" there isn't really just > // the one simple selector. Technically this compound > // selector contains the pseudo element selector as well > // -- Combinator::PseudoElement, just like > // Combinator::SlotAssignment, don't exist in the > // spec. >- (Some(Combinator::PseudoElement), _) | >- (Some(Combinator::SlotAssignment), _) => (), >+ (Some(Combinator::PseudoElement), _) >+ | (Some(Combinator::SlotAssignment), _) => (), > (_, &Component::ExplicitUniversalType) => { > // Iterate over everything so we serialize the namespace > // too. > for simple in compound.iter() { > simple.to_css(dest)?; > } > // Skip step 2, which is an "otherwise". > perform_step_2 = false; >- }, >+ } > _ => (), > } > } > > // 2. Otherwise, for each simple selector in the compound selectors > // that is not a universal selector of which the namespace prefix > // maps to a namespace that is not the default namespace > // serialize the simple selector and append the result to s. >@@ -1153,139 +1161,139 @@ impl<Impl: SelectorImpl> ToCss for Component<Impl> { > } > > match *self { > Combinator(ref c) => c.to_css(dest), > Slotted(ref selector) => { > dest.write_str("::slotted(")?; > selector.to_css(dest)?; > dest.write_char(')') >- }, >+ } > PseudoElement(ref p) => p.to_css(dest), > ID(ref s) => { > dest.write_char('#')?; > display_to_css_identifier(s, dest) >- }, >+ } > Class(ref s) => { > dest.write_char('.')?; > display_to_css_identifier(s, dest) >- }, >+ } > LocalName(ref s) => s.to_css(dest), > ExplicitUniversalType => dest.write_char('*'), > > DefaultNamespace(_) => Ok(()), > ExplicitNoNamespace => dest.write_char('|'), > ExplicitAnyNamespace => dest.write_str("*|"), > Namespace(ref prefix, _) => { > display_to_css_identifier(prefix, dest)?; > dest.write_char('|') >- }, >+ } > > AttributeInNoNamespaceExists { ref local_name, .. } => { > dest.write_char('[')?; > display_to_css_identifier(local_name, dest)?; > dest.write_char(']') >- }, >+ } > AttributeInNoNamespace { > ref local_name, > operator, > ref value, > case_sensitivity, > .. > } => { > dest.write_char('[')?; > display_to_css_identifier(local_name, dest)?; > operator.to_css(dest)?; > dest.write_char('"')?; > write!(CssStringWriter::new(dest), "{}", value)?; > dest.write_char('"')?; > match case_sensitivity { >- ParsedCaseSensitivity::CaseSensitive | >- ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {}, >+ ParsedCaseSensitivity::CaseSensitive >+ | ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {} > ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?, > } > dest.write_char(']') >- }, >+ } > AttributeOther(ref attr_selector) => attr_selector.to_css(dest), > > // Pseudo-classes > Negation(ref arg) => { > dest.write_str(":not(")?; > for component in arg.iter() { > component.to_css(dest)?; > } > dest.write_str(")") >- }, >+ } > > FirstChild => dest.write_str(":first-child"), > LastChild => dest.write_str(":last-child"), > OnlyChild => dest.write_str(":only-child"), > Root => dest.write_str(":root"), > Empty => dest.write_str(":empty"), > Scope => dest.write_str(":scope"), > Host(ref selector) => { > dest.write_str(":host")?; > if let Some(ref selector) = *selector { > dest.write_char('(')?; > selector.to_css(dest)?; > dest.write_char(')')?; > } > Ok(()) >- }, >+ } > FirstOfType => dest.write_str(":first-of-type"), > LastOfType => dest.write_str(":last-of-type"), > OnlyOfType => dest.write_str(":only-of-type"), > NthChild(a, b) | NthLastChild(a, b) | NthOfType(a, b) | NthLastOfType(a, b) => { > match *self { > NthChild(_, _) => dest.write_str(":nth-child(")?, > NthLastChild(_, _) => dest.write_str(":nth-last-child(")?, > NthOfType(_, _) => dest.write_str(":nth-of-type(")?, > NthLastOfType(_, _) => dest.write_str(":nth-last-of-type(")?, > _ => unreachable!(), > } > write_affine(dest, a, b)?; > dest.write_char(')') >- }, >+ } > NonTSPseudoClass(ref pseudo) => pseudo.to_css(dest), > } > } > } > > impl<Impl: SelectorImpl> ToCss for AttrSelectorWithOptionalNamespace<Impl> { > fn to_css<W>(&self, dest: &mut W) -> fmt::Result > where > W: fmt::Write, > { > dest.write_char('[')?; > match self.namespace { > Some(NamespaceConstraint::Specific((ref prefix, _))) => { > display_to_css_identifier(prefix, dest)?; > dest.write_char('|')? >- }, >+ } > Some(NamespaceConstraint::Any) => dest.write_str("*|")?, > None => {} > } > display_to_css_identifier(&self.local_name, dest)?; > match self.operation { >- ParsedAttrSelectorOperation::Exists => {}, >+ ParsedAttrSelectorOperation::Exists => {} > ParsedAttrSelectorOperation::WithValue { > operator, > case_sensitivity, > ref expected_value, > } => { > operator.to_css(dest)?; > dest.write_char('"')?; > write!(CssStringWriter::new(dest), "{}", expected_value)?; > dest.write_char('"')?; > match case_sensitivity { >- ParsedCaseSensitivity::CaseSensitive | >- ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {}, >+ ParsedCaseSensitivity::CaseSensitive >+ | ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument => {} > ParsedCaseSensitivity::AsciiCaseInsensitive => dest.write_str(" i")?, > } >- }, >+ } > } > dest.write_char(']') > } > } > > impl<Impl: SelectorImpl> ToCss for LocalName<Impl> { > fn to_css<W>(&self, dest: &mut W) -> fmt::Result > where >@@ -1331,24 +1339,24 @@ where > let mut has_pseudo_element; > let mut slotted; > 'outer_loop: loop { > // Parse a sequence of simple selectors. > match parse_compound_selector(parser, input, &mut builder)? { > Some((has_pseudo, slot)) => { > has_pseudo_element = has_pseudo; > slotted = slot; >- }, >+ } > None => { > return Err(input.new_custom_error(if builder.has_combinators() { > SelectorParseErrorKind::DanglingCombinator > } else { > SelectorParseErrorKind::EmptySelector > })) >- }, >+ } > }; > > if has_pseudo_element || slotted { > break; > } > > // Parse a combinator. > let combinator; >@@ -1356,34 +1364,34 @@ where > loop { > let before_this_token = input.state(); > match input.next_including_whitespace() { > Err(_e) => break 'outer_loop, > Ok(&Token::WhiteSpace(_)) => any_whitespace = true, > Ok(&Token::Delim('>')) => { > combinator = Combinator::Child; > break; >- }, >+ } > Ok(&Token::Delim('+')) => { > combinator = Combinator::NextSibling; > break; >- }, >+ } > Ok(&Token::Delim('~')) => { > combinator = Combinator::LaterSibling; > break; >- }, >+ } > Ok(_) => { > input.reset(&before_this_token); > if any_whitespace { > combinator = Combinator::Descendant; > break; > } else { > break 'outer_loop; > } >- }, >+ } > } > } > builder.push_combinator(combinator); > } > > Ok(Selector(builder.build(has_pseudo_element, slotted))) > } > >@@ -1417,63 +1425,63 @@ where > P: Parser<'i, Impl = Impl>, > Impl: SelectorImpl, > S: Push<Component<Impl>>, > { > match parse_qualified_name(parser, input, /* in_attr_selector = */ false) { > Err(ParseError { > kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), > .. >- }) | >- Ok(OptionalQName::None(_)) => Ok(false), >+ }) >+ | Ok(OptionalQName::None(_)) => Ok(false), > Ok(OptionalQName::Some(namespace, local_name)) => { > match namespace { >- QNamePrefix::ImplicitAnyNamespace => {}, >+ QNamePrefix::ImplicitAnyNamespace => {} > QNamePrefix::ImplicitDefaultNamespace(url) => { > sink.push(Component::DefaultNamespace(url)) >- }, >+ } > QNamePrefix::ExplicitNamespace(prefix, url) => { > sink.push(match parser.default_namespace() { > Some(ref default_url) if url == *default_url => { > Component::DefaultNamespace(url) >- }, >+ } > _ => Component::Namespace(prefix, url), > }) >- }, >+ } > QNamePrefix::ExplicitNoNamespace => sink.push(Component::ExplicitNoNamespace), > QNamePrefix::ExplicitAnyNamespace => { > match parser.default_namespace() { > // Element type selectors that have no namespace > // component (no namespace separator) represent elements > // without regard to the element's namespace (equivalent > // to "*|") unless a default namespace has been declared > // for namespaced selectors (e.g. in CSS, in the style > // sheet). If a default namespace has been declared, > // such selectors will represent only elements in the > // default namespace. > // -- Selectors § 6.1.1 > // So we'll have this act the same as the > // QNamePrefix::ImplicitAnyNamespace case. >- None => {}, >+ None => {} > Some(_) => sink.push(Component::ExplicitAnyNamespace), > } >- }, >+ } > QNamePrefix::ImplicitNoNamespace => { > unreachable!() // Not returned with in_attr_selector = false >- }, >+ } > } > match local_name { > Some(name) => sink.push(Component::LocalName(LocalName { > lower_name: to_ascii_lowercase(&name).as_ref().into(), > name: name.as_ref().into(), > })), > None => sink.push(Component::ExplicitUniversalType), > } > Ok(true) >- }, >+ } > Err(e) => Err(e), > } > } > > #[derive(Debug)] > enum SimpleSelectorParseResult<Impl: SelectorImpl> { > SimpleSelector(Component<Impl>), > PseudoElement(Impl::PseudoElement), >@@ -1517,21 +1525,21 @@ where > }; > > let explicit_namespace = |input: &mut CssParser<'i, 't>, namespace| { > let location = input.current_source_location(); > match input.next_including_whitespace() { > Ok(&Token::Delim('*')) if !in_attr_selector => Ok(OptionalQName::Some(namespace, None)), > Ok(&Token::Ident(ref local_name)) => { > Ok(OptionalQName::Some(namespace, Some(local_name.clone()))) >- }, >+ } > Ok(t) if in_attr_selector => { > let e = SelectorParseErrorKind::InvalidQualNameInAttr(t.clone()); > Err(location.new_custom_error(e)) >- }, >+ } > Ok(t) => Err(location.new_custom_error( > SelectorParseErrorKind::ExplicitNamespaceUnexpectedToken(t.clone()), > )), > Err(e) => Err(e.into()), > } > }; > > let start = input.state(); >@@ -1544,61 +1552,61 @@ where > let prefix = value.as_ref().into(); > let result = parser.namespace_for_prefix(&prefix); > let url = result.ok_or( > after_ident > .source_location() > .new_custom_error(SelectorParseErrorKind::ExpectedNamespace(value)), > )?; > explicit_namespace(input, QNamePrefix::ExplicitNamespace(prefix, url)) >- }, >+ } > _ => { > input.reset(&after_ident); > if in_attr_selector { > Ok(OptionalQName::Some( > QNamePrefix::ImplicitNoNamespace, > Some(value), > )) > } else { > default_namespace(Some(value)) > } >- }, >+ } > } >- }, >+ } > Ok(Token::Delim('*')) => { > let after_star = input.state(); > // FIXME: remove clone() when lifetimes are non-lexical > match input.next_including_whitespace().map(|t| t.clone()) { > Ok(Token::Delim('|')) => { > explicit_namespace(input, QNamePrefix::ExplicitAnyNamespace) >- }, >+ } > result => { > input.reset(&after_star); > if in_attr_selector { > match result { > Ok(t) => Err(after_star > .source_location() > .new_custom_error(SelectorParseErrorKind::ExpectedBarInAttr(t))), > Err(e) => Err(e.into()), > } > } else { > default_namespace(None) > } >- }, >+ } > } >- }, >+ } > Ok(Token::Delim('|')) => explicit_namespace(input, QNamePrefix::ExplicitNoNamespace), > Ok(t) => { > input.reset(&start); > Ok(OptionalQName::None(t)) >- }, >+ } > Err(e) => { > input.reset(&start); > Err(e.into()) >- }, >+ } > } > } > > fn parse_attribute_selector<'i, 't, P, Impl>( > parser: &P, > input: &mut CssParser<'i, 't>, > ) -> Result<Component<Impl>, ParseError<'i, P::Error>> > where >@@ -1610,31 +1618,31 @@ where > > input.skip_whitespace(); > > match parse_qualified_name(parser, input, /* in_attr_selector = */ true)? { > OptionalQName::None(t) => { > return Err(input.new_custom_error( > SelectorParseErrorKind::NoQualifiedNameInAttributeSelector(t), > )) >- }, >+ } > OptionalQName::Some(_, None) => unreachable!(), > OptionalQName::Some(ns, Some(ln)) => { > local_name = ln; > namespace = match ns { > QNamePrefix::ImplicitNoNamespace | QNamePrefix::ExplicitNoNamespace => None, > QNamePrefix::ExplicitNamespace(prefix, url) => { > Some(NamespaceConstraint::Specific((prefix, url))) >- }, >+ } > QNamePrefix::ExplicitAnyNamespace => Some(NamespaceConstraint::Any), > QNamePrefix::ImplicitAnyNamespace | QNamePrefix::ImplicitDefaultNamespace(_) => { > unreachable!() // Not returned with in_attr_selector = true >- }, >+ } > } >- }, >+ } > } > > let location = input.current_source_location(); > let operator = match input.next() { > // [foo] > Err(_) => { > let local_name_lower = to_ascii_lowercase(&local_name).as_ref().into(); > let local_name = local_name.as_ref().into(); >@@ -1649,17 +1657,17 @@ where > }, > ))); > } else { > return Ok(Component::AttributeInNoNamespaceExists { > local_name: local_name, > local_name_lower: local_name_lower, > }); > } >- }, >+ } > > // [foo=bar] > Ok(&Token::Delim('=')) => AttrSelectorOperator::Equal, > // [foo~=bar] > Ok(&Token::IncludeMatch) => AttrSelectorOperator::Includes, > // [foo|=bar] > Ok(&Token::DashMatch) => AttrSelectorOperator::DashMatch, > // [foo^=bar] >@@ -1667,50 +1675,49 @@ where > // [foo*=bar] > Ok(&Token::SubstringMatch) => AttrSelectorOperator::Substring, > // [foo$=bar] > Ok(&Token::SuffixMatch) => AttrSelectorOperator::Suffix, > Ok(t) => { > return Err(location.new_custom_error( > SelectorParseErrorKind::UnexpectedTokenInAttributeSelector(t.clone()), > )) >- }, >+ } > }; > > let value = match input.expect_ident_or_string() { > Ok(t) => t.clone(), > Err(BasicParseError { > kind: BasicParseErrorKind::UnexpectedToken(t), > location, > }) => return Err(location.new_custom_error(SelectorParseErrorKind::BadValueInAttr(t))), > Err(e) => return Err(e.into()), > }; > let never_matches = match operator { > AttrSelectorOperator::Equal | AttrSelectorOperator::DashMatch => false, > > AttrSelectorOperator::Includes => value.is_empty() || value.contains(SELECTOR_WHITESPACE), > >- AttrSelectorOperator::Prefix | >- AttrSelectorOperator::Substring | >- AttrSelectorOperator::Suffix => value.is_empty(), >+ AttrSelectorOperator::Prefix >+ | AttrSelectorOperator::Substring >+ | AttrSelectorOperator::Suffix => value.is_empty(), > }; > > let mut case_sensitivity = parse_attribute_flags(input)?; > > let value = value.as_ref().into(); > let local_name_lower; > let local_name_is_ascii_lowercase; > { > let local_name_lower_cow = to_ascii_lowercase(&local_name); > if let ParsedCaseSensitivity::CaseSensitive = case_sensitivity { >- if namespace.is_none() && >- include!(concat!( >- env!("OUT_DIR"), >- "/ascii_case_insensitive_html_attributes.rs" >- )).contains(&*local_name_lower_cow) >+ if namespace.is_none() && include!(concat!( >+ env!("OUT_DIR"), >+ "/ascii_case_insensitive_html_attributes.rs" >+ )).contains(&*local_name_lower_cow) > { > case_sensitivity = > ParsedCaseSensitivity::AsciiCaseInsensitiveIfInHtmlElementInHtmlDocument > } > } > local_name_lower = local_name_lower_cow.as_ref().into(); > local_name_is_ascii_lowercase = matches!(local_name_lower_cow, Cow::Borrowed(..)); > } >@@ -1743,20 +1750,20 @@ where > fn parse_attribute_flags<'i, 't>( > input: &mut CssParser<'i, 't>, > ) -> Result<ParsedCaseSensitivity, BasicParseError<'i>> { > let location = input.current_source_location(); > match input.next() { > Err(_) => { > // Selectors spec says language-defined, but HTML says sensitive. > Ok(ParsedCaseSensitivity::CaseSensitive) >- }, >+ } > Ok(&Token::Ident(ref value)) if value.eq_ignore_ascii_case("i") => { > Ok(ParsedCaseSensitivity::AsciiCaseInsensitive) >- }, >+ } > Ok(t) => Err(location.new_basic_unexpected_token_error(t.clone())), > } > } > > /// Level 3: Parse **one** simple_selector. (Though we might insert a second > /// implied "<defaultns>|*" type selector.) > fn parse_negation<'i, 't, P, Impl>( > parser: &P, >@@ -1780,30 +1787,32 @@ where > .. > }) => return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)), > Err(e) => return Err(e.into()), > }; > if !is_type_sel { > match parse_one_simple_selector(parser, input, /* inside_negation = */ true)? { > Some(SimpleSelectorParseResult::SimpleSelector(s)) => { > sequence.push(s); >- }, >+ } > None => { > return Err(input.new_custom_error(SelectorParseErrorKind::EmptyNegation)); >- }, >- Some(SimpleSelectorParseResult::PseudoElement(_)) | >- Some(SimpleSelectorParseResult::SlottedPseudo(_)) => { >+ } >+ Some(SimpleSelectorParseResult::PseudoElement(_)) >+ | Some(SimpleSelectorParseResult::SlottedPseudo(_)) => { > let e = SelectorParseErrorKind::NonSimpleSelectorInNegation; > return Err(input.new_custom_error(e)); >- }, >+ } > } > } > > // Success. >- Ok(Component::Negation(sequence.into_vec().into_boxed_slice().into())) >+ Ok(Component::Negation( >+ sequence.into_vec().into_boxed_slice().into(), >+ )) > } > > /// simple_selector_sequence > /// : [ type_selector | universal ] [ HASH | class | attrib | pseudo | negation ]* > /// | [ HASH | class | attrib | pseudo | negation ]+ > /// > /// `Err(())` means invalid selector. > /// `Ok(None)` is an empty selector >@@ -1841,43 +1850,43 @@ where > None => break, > Some(result) => result, > }; > > match parse_result { > SimpleSelectorParseResult::SimpleSelector(s) => { > builder.push_simple_selector(s); > empty = false >- }, >+ } > SimpleSelectorParseResult::PseudoElement(p) => { > // Try to parse state to its right. There are only 3 allowable > // state selectors that can go on pseudo-elements. > let mut state_selectors = SmallVec::<[Component<Impl>; 3]>::new(); > > loop { > let location = input.current_source_location(); > match input.next_including_whitespace() { >- Ok(&Token::Colon) => {}, >+ Ok(&Token::Colon) => {} > Ok(&Token::WhiteSpace(_)) | Err(_) => break, > Ok(t) => { > let e = SelectorParseErrorKind::PseudoElementExpectedColon(t.clone()); > return Err(location.new_custom_error(e)); >- }, >+ } > } > > let location = input.current_source_location(); > // TODO(emilio): Functional pseudo-classes too? > // We don't need it for now. > let name = match input.next_including_whitespace()? { > &Token::Ident(ref name) => name.clone(), > t => { > return Err(location.new_custom_error( > SelectorParseErrorKind::NoIdentForPseudo(t.clone()), > )) >- }, >+ } > }; > > let pseudo_class = > P::parse_non_ts_pseudo_class(parser, location, name.clone())?; > if !p.supports_pseudo_class(&pseudo_class) { > return Err(input.new_custom_error( > SelectorParseErrorKind::UnsupportedPseudoClassOrElement(name), > )); >@@ -1892,29 +1901,29 @@ where > builder.push_simple_selector(Component::PseudoElement(p)); > for state_selector in state_selectors.drain() { > builder.push_simple_selector(state_selector); > } > > pseudo = true; > empty = false; > break; >- }, >+ } > SimpleSelectorParseResult::SlottedPseudo(selector) => { > empty = false; > slot = true; > if !builder.is_empty() { > builder.push_combinator(Combinator::SlotAssignment); > } > builder.push_simple_selector(Component::Slotted(selector)); > // FIXME(emilio): ::slotted() should support ::before and > // ::after after it, so we shouldn't break, but we shouldn't > // push more type selectors either. > break; >- }, >+ } > } > } > if empty { > // An empty selector is invalid. > Ok(None) > } else { > Ok(Some((pseudo, slot))) > } >@@ -1987,47 +1996,47 @@ where > Impl: SelectorImpl, > { > let start = input.state(); > // FIXME: remove clone() when lifetimes are non-lexical > match input.next_including_whitespace().map(|t| t.clone()) { > Ok(Token::IDHash(id)) => { > let id = Component::ID(id.as_ref().into()); > Ok(Some(SimpleSelectorParseResult::SimpleSelector(id))) >- }, >+ } > Ok(Token::Delim('.')) => { > let location = input.current_source_location(); > match *input.next_including_whitespace()? { > Token::Ident(ref class) => { > let class = Component::Class(class.as_ref().into()); > Ok(Some(SimpleSelectorParseResult::SimpleSelector(class))) >- }, >+ } > ref t => { > let e = SelectorParseErrorKind::ClassNeedsIdent(t.clone()); > Err(location.new_custom_error(e)) >- }, >+ } > } >- }, >+ } > Ok(Token::SquareBracketBlock) => { > let attr = input.parse_nested_block(|input| parse_attribute_selector(parser, input))?; > Ok(Some(SimpleSelectorParseResult::SimpleSelector(attr))) >- }, >+ } > Ok(Token::Colon) => { > let location = input.current_source_location(); > let (is_single_colon, next_token) = match input.next_including_whitespace()?.clone() { > Token::Colon => (false, input.next_including_whitespace()?.clone()), > t => (true, t), > }; > let (name, is_functional) = match next_token { > Token::Ident(name) => (name, false), > Token::Function(name) => (name, true), > t => { > let e = SelectorParseErrorKind::PseudoElementExpectedIdent(t); > return Err(input.new_custom_error(e)); >- }, >+ } > }; > let is_pseudo_element = > !is_single_colon || P::pseudo_element_allows_single_colon(&name); > if is_pseudo_element { > let parse_result = if is_functional { > if P::parse_slotted(parser) && name.eq_ignore_ascii_case("slotted") { > let selector = input.parse_nested_block(|input| { > parse_inner_compound_selector(parser, input) >@@ -2036,39 +2045,37 @@ where > } else { > let selector = input.parse_nested_block(|input| { > P::parse_functional_pseudo_element(parser, name, input) > })?; > SimpleSelectorParseResult::PseudoElement(selector) > } > } else { > SimpleSelectorParseResult::PseudoElement(P::parse_pseudo_element( >- parser, >- location, >- name, >+ parser, location, name, > )?) > }; > Ok(Some(parse_result)) > } else { > let pseudo_class = if is_functional { > input.parse_nested_block(|input| { > parse_functional_pseudo_class(parser, input, name, inside_negation) > })? > } else { > parse_simple_pseudo_class(parser, location, name)? > }; > Ok(Some(SimpleSelectorParseResult::SimpleSelector( > pseudo_class, > ))) > } >- }, >+ } > _ => { > input.reset(&start); > Ok(None) >- }, >+ } > } > } > > fn parse_simple_pseudo_class<'i, P, Impl>( > parser: &P, > location: SourceLocation, > name: CowRcStr<'i>, > ) -> Result<Component<Impl>, ParseError<'i, P::Error>> >@@ -2091,22 +2098,22 @@ where > }).or_else(|()| { > P::parse_non_ts_pseudo_class(parser, location, name).map(Component::NonTSPseudoClass) > }) > } > > // NB: pub module in order to access the DummyParser > #[cfg(test)] > pub mod tests { >+ use super::*; > use builder::HAS_PSEUDO_BIT; > use cssparser::{serialize_identifier, Parser as CssParser, ParserInput, ToCss}; > use parser; > use std::collections::HashMap; > use std::fmt; >- use super::*; > > #[derive(Clone, Debug, Eq, PartialEq)] > pub enum PseudoClass { > Hover, > Active, > Lang(String), > } > >@@ -2143,17 +2150,17 @@ pub mod tests { > { > match *self { > PseudoClass::Hover => dest.write_str(":hover"), > PseudoClass::Active => dest.write_str(":active"), > PseudoClass::Lang(ref lang) => { > dest.write_str(":lang(")?; > serialize_identifier(lang, dest)?; > dest.write_char(')') >- }, >+ } > } > } > } > > impl ToCss for PseudoElement { > fn to_css<W>(&self, dest: &mut W) -> fmt::Result > where > W: fmt::Write, >@@ -2358,521 +2365,452 @@ pub mod tests { > > #[test] > fn test_parsing() { > assert!(parse("").is_err()); > assert!(parse(":lang(4)").is_err()); > assert!(parse(":lang(en US)").is_err()); > assert_eq!( > parse("EeÃ"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::LocalName(LocalName { >- name: DummyAtom::from("EeÃ"), >- lower_name: DummyAtom::from("eeÃ"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::LocalName(LocalName { >+ name: DummyAtom::from("EeÃ"), >+ lower_name: DummyAtom::from("eeÃ"), >+ }),], >+ specificity(0, 0, 1), >+ ),])) > ); > assert_eq!( > parse("|e"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ExplicitNoNamespace, >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ExplicitNoNamespace, >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ ], >+ specificity(0, 0, 1), >+ ),])) > ); > // When the default namespace is not set, *| should be elided. > // https://github.com/servo/servo/pull/17537 > assert_eq!( > parse_expected("*|e", Some("e")), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }),], >+ specificity(0, 0, 1), >+ ),])) > ); > // When the default namespace is set, *| should _not_ be elided (as foo > // is no longer equivalent to *|foo--the former is only for foo in the > // default namespace). > // https://github.com/servo/servo/issues/16020 > assert_eq!( > parse_ns( > "*|e", > &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org")) > ), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ExplicitAnyNamespace, >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ExplicitAnyNamespace, >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ ], >+ specificity(0, 0, 1), >+ ),])) > ); > assert_eq!( > parse("*"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec(vec![Component::ExplicitUniversalType], specificity(0, 0, 0)), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::ExplicitUniversalType], >+ specificity(0, 0, 0) >+ ),])) > ); > assert_eq!( > parse("|*"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ExplicitNoNamespace, >- Component::ExplicitUniversalType, >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ExplicitNoNamespace, >+ Component::ExplicitUniversalType, >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse_expected("*|*", Some("*")), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec(vec![Component::ExplicitUniversalType], specificity(0, 0, 0)), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::ExplicitUniversalType], >+ specificity(0, 0, 0) >+ ),])) > ); > assert_eq!( > parse_ns( > "*|*", > &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org")) > ), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ExplicitAnyNamespace, >- Component::ExplicitUniversalType, >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ExplicitAnyNamespace, >+ Component::ExplicitUniversalType, >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse(".foo:lang(en-US)"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Class(DummyAtom::from("foo")), >- Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())), >- ], >- specificity(0, 2, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::Class(DummyAtom::from("foo")), >+ Component::NonTSPseudoClass(PseudoClass::Lang("en-US".to_owned())), >+ ], >+ specificity(0, 2, 0), >+ ),])) > ); > assert_eq!( > parse("#bar"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![Component::ID(DummyAtom::from("bar"))], >- specificity(1, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::ID(DummyAtom::from("bar"))], >+ specificity(1, 0, 0), >+ ),])) > ); > assert_eq!( > parse("e.foo#bar"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- Component::Class(DummyAtom::from("foo")), >- Component::ID(DummyAtom::from("bar")), >- ], >- specificity(1, 1, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ Component::Class(DummyAtom::from("foo")), >+ Component::ID(DummyAtom::from("bar")), >+ ], >+ specificity(1, 1, 1), >+ ),])) > ); > assert_eq!( > parse("e.foo #bar"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- Component::Class(DummyAtom::from("foo")), >- Component::Combinator(Combinator::Descendant), >- Component::ID(DummyAtom::from("bar")), >- ], >- specificity(1, 1, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ Component::Class(DummyAtom::from("foo")), >+ Component::Combinator(Combinator::Descendant), >+ Component::ID(DummyAtom::from("bar")), >+ ], >+ specificity(1, 1, 1), >+ ),])) > ); > // Default namespace does not apply to attribute selectors > // https://github.com/mozilla/servo/pull/1652 > let mut parser = DummyParser::default(); > assert_eq!( > parse_ns("[Foo]", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::AttributeInNoNamespaceExists { >- local_name: DummyAtom::from("Foo"), >- local_name_lower: DummyAtom::from("foo"), >- }, >- ], >- specificity(0, 1, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::AttributeInNoNamespaceExists { >+ local_name: DummyAtom::from("Foo"), >+ local_name_lower: DummyAtom::from("foo"), >+ },], >+ specificity(0, 1, 0), >+ ),])) > ); > assert!(parse_ns("svg|circle", &parser).is_err()); > parser > .ns_prefixes > .insert(DummyAtom("svg".into()), DummyAtom(SVG.into())); > assert_eq!( > parse_ns("svg|circle", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Namespace(DummyAtom("svg".into()), SVG.into()), >- Component::LocalName(LocalName { >- name: DummyAtom::from("circle"), >- lower_name: DummyAtom::from("circle"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::Namespace(DummyAtom("svg".into()), SVG.into()), >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("circle"), >+ lower_name: DummyAtom::from("circle"), >+ }), >+ ], >+ specificity(0, 0, 1), >+ ),])) > ); > assert_eq!( > parse_ns("svg|*", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Namespace(DummyAtom("svg".into()), SVG.into()), >- Component::ExplicitUniversalType, >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::Namespace(DummyAtom("svg".into()), SVG.into()), >+ Component::ExplicitUniversalType, >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > // Default namespace does not apply to attribute selectors > // https://github.com/mozilla/servo/pull/1652 > // but it does apply to implicit type selectors > // https://github.com/servo/rust-selectors/pull/82 > parser.default_ns = Some(MATHML.into()); > assert_eq!( > parse_ns("[Foo]", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::AttributeInNoNamespaceExists { >- local_name: DummyAtom::from("Foo"), >- local_name_lower: DummyAtom::from("foo"), >- }, >- ], >- specificity(0, 1, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::AttributeInNoNamespaceExists { >+ local_name: DummyAtom::from("Foo"), >+ local_name_lower: DummyAtom::from("foo"), >+ }, >+ ], >+ specificity(0, 1, 0), >+ ),])) > ); > // Default namespace does apply to type selectors > assert_eq!( > parse_ns("e", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ ], >+ specificity(0, 0, 1), >+ ),])) > ); > assert_eq!( > parse_ns("*", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::ExplicitUniversalType, >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::ExplicitUniversalType, >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse_ns("*|*", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ExplicitAnyNamespace, >- Component::ExplicitUniversalType, >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ExplicitAnyNamespace, >+ Component::ExplicitUniversalType, >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > // Default namespace applies to universal and type selectors inside :not and :matches, > // but not otherwise. > assert_eq!( > parse_ns(":not(.cl)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::Negation( >- vec![Component::Class(DummyAtom::from("cl"))].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 1, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::Negation( >+ vec![Component::Class(DummyAtom::from("cl"))] >+ .into_boxed_slice() >+ .into(), >+ ), >+ ], >+ specificity(0, 1, 0), >+ ),])) > ); > assert_eq!( > parse_ns(":not(*)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::Negation( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::ExplicitUniversalType, >- ].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::Negation( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::ExplicitUniversalType, >+ ].into_boxed_slice() >+ .into(), >+ ), >+ ], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse_ns(":not(e)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::Negation( >- vec![ >- Component::DefaultNamespace(MATHML.into()), >- Component::LocalName(LocalName { >- name: DummyAtom::from("e"), >- lower_name: DummyAtom::from("e"), >- }), >- ].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::Negation( >+ vec![ >+ Component::DefaultNamespace(MATHML.into()), >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("e"), >+ lower_name: DummyAtom::from("e"), >+ }), >+ ].into_boxed_slice() >+ .into(), >+ ), >+ ], >+ specificity(0, 0, 1), >+ ),])) > ); > assert_eq!( > parse("[attr|=\"foo\"]"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::AttributeInNoNamespace { >- local_name: DummyAtom::from("attr"), >- operator: AttrSelectorOperator::DashMatch, >- value: DummyAtom::from("foo"), >- never_matches: false, >- case_sensitivity: ParsedCaseSensitivity::CaseSensitive, >- }, >- ], >- specificity(0, 1, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::AttributeInNoNamespace { >+ local_name: DummyAtom::from("attr"), >+ operator: AttrSelectorOperator::DashMatch, >+ value: DummyAtom::from("foo"), >+ never_matches: false, >+ case_sensitivity: ParsedCaseSensitivity::CaseSensitive, >+ },], >+ specificity(0, 1, 0), >+ ),])) > ); > // https://github.com/mozilla/servo/issues/1723 > assert_eq!( > parse("::before"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![Component::PseudoElement(PseudoElement::Before)], >- specificity(0, 0, 1) | HAS_PSEUDO_BIT, >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::PseudoElement(PseudoElement::Before)], >+ specificity(0, 0, 1) | HAS_PSEUDO_BIT, >+ ),])) > ); > assert_eq!( > parse("::before:hover"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::PseudoElement(PseudoElement::Before), >- Component::NonTSPseudoClass(PseudoClass::Hover), >- ], >- specificity(0, 1, 1) | HAS_PSEUDO_BIT, >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::PseudoElement(PseudoElement::Before), >+ Component::NonTSPseudoClass(PseudoClass::Hover), >+ ], >+ specificity(0, 1, 1) | HAS_PSEUDO_BIT, >+ ),])) > ); > assert_eq!( > parse("::before:hover:hover"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::PseudoElement(PseudoElement::Before), >- Component::NonTSPseudoClass(PseudoClass::Hover), >- Component::NonTSPseudoClass(PseudoClass::Hover), >- ], >- specificity(0, 2, 1) | HAS_PSEUDO_BIT, >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::PseudoElement(PseudoElement::Before), >+ Component::NonTSPseudoClass(PseudoClass::Hover), >+ Component::NonTSPseudoClass(PseudoClass::Hover), >+ ], >+ specificity(0, 2, 1) | HAS_PSEUDO_BIT, >+ ),])) > ); > assert!(parse("::before:hover:active").is_err()); > assert!(parse("::before:hover .foo").is_err()); > assert!(parse("::before .foo").is_err()); > assert!(parse("::before ~ bar").is_err()); > assert!(parse("::before:active").is_err()); > > // https://github.com/servo/servo/issues/15335 > assert!(parse(":: before").is_err()); > assert_eq!( > parse("div ::after"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::LocalName(LocalName { >- name: DummyAtom::from("div"), >- lower_name: DummyAtom::from("div"), >- }), >- Component::Combinator(Combinator::Descendant), >- Component::Combinator(Combinator::PseudoElement), >- Component::PseudoElement(PseudoElement::After), >- ], >- specificity(0, 0, 2) | HAS_PSEUDO_BIT, >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("div"), >+ lower_name: DummyAtom::from("div"), >+ }), >+ Component::Combinator(Combinator::Descendant), >+ Component::Combinator(Combinator::PseudoElement), >+ Component::PseudoElement(PseudoElement::After), >+ ], >+ specificity(0, 0, 2) | HAS_PSEUDO_BIT, >+ ),])) > ); > assert_eq!( > parse("#d1 > .ok"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::ID(DummyAtom::from("d1")), >- Component::Combinator(Combinator::Child), >- Component::Class(DummyAtom::from("ok")), >- ], >- (1 << 20) + (1 << 10) + (0 << 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![ >+ Component::ID(DummyAtom::from("d1")), >+ Component::Combinator(Combinator::Child), >+ Component::Class(DummyAtom::from("ok")), >+ ], >+ (1 << 20) + (1 << 10) + (0 << 0), >+ ),])) > ); > parser.default_ns = None; > assert!(parse(":not(#provel.old)").is_err()); > assert!(parse(":not(#provel > old)").is_err()); > assert!(parse("table[rules]:not([rules=\"none\"]):not([rules=\"\"])").is_ok()); > assert_eq!( > parse(":not(#provel)"), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Negation( >- vec![Component::ID(DummyAtom::from("provel"))].into_boxed_slice().into(), >- ), >- ], >- specificity(1, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( >+ vec![Component::ID(DummyAtom::from("provel"))] >+ .into_boxed_slice() >+ .into(), >+ ),], >+ specificity(1, 0, 0), >+ ),])) > ); > assert_eq!( > parse_ns(":not(svg|circle)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( > vec![ >- Component::Negation( >- vec![ >- Component::Namespace(DummyAtom("svg".into()), SVG.into()), >- Component::LocalName(LocalName { >- name: DummyAtom::from("circle"), >- lower_name: DummyAtom::from("circle"), >- }), >- ].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 1), >- ), >- ])) >+ Component::Namespace(DummyAtom("svg".into()), SVG.into()), >+ Component::LocalName(LocalName { >+ name: DummyAtom::from("circle"), >+ lower_name: DummyAtom::from("circle"), >+ }), >+ ].into_boxed_slice() >+ .into(), >+ ),], >+ specificity(0, 0, 1), >+ ),])) > ); > // https://github.com/servo/servo/issues/16017 > assert_eq!( > parse_ns(":not(*)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Negation( >- vec![Component::ExplicitUniversalType].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( >+ vec![Component::ExplicitUniversalType] >+ .into_boxed_slice() >+ .into(), >+ ),], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse_ns(":not(|*)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( > vec![ >- Component::Negation( >- vec![ >- Component::ExplicitNoNamespace, >- Component::ExplicitUniversalType, >- ].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Component::ExplicitNoNamespace, >+ Component::ExplicitUniversalType, >+ ].into_boxed_slice() >+ .into(), >+ ),], >+ specificity(0, 0, 0), >+ ),])) > ); > // *| should be elided if there is no default namespace. > // https://github.com/servo/servo/pull/17537 > assert_eq!( > parse_ns_expected(":not(*|*)", &parser, Some(":not(*)")), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >- vec![ >- Component::Negation( >- vec![Component::ExplicitUniversalType].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( >+ vec![Component::ExplicitUniversalType] >+ .into_boxed_slice() >+ .into(), >+ ),], >+ specificity(0, 0, 0), >+ ),])) > ); > assert_eq!( > parse_ns(":not(svg|*)", &parser), >- Ok(SelectorList::from_vec(vec![ >- Selector::from_vec( >+ Ok(SelectorList::from_vec(vec![Selector::from_vec( >+ vec![Component::Negation( > vec![ >- Component::Negation( >- vec![ >- Component::Namespace(DummyAtom("svg".into()), SVG.into()), >- Component::ExplicitUniversalType, >- ].into_boxed_slice().into(), >- ), >- ], >- specificity(0, 0, 0), >- ), >- ])) >+ Component::Namespace(DummyAtom("svg".into()), SVG.into()), >+ Component::ExplicitUniversalType, >+ ].into_boxed_slice() >+ .into(), >+ ),], >+ specificity(0, 0, 0), >+ ),])) > ); > > assert!(parse("::slotted()").is_err()); > assert!(parse("::slotted(div)").is_ok()); > assert!(parse("::slotted(div).foo").is_err()); > assert!(parse("::slotted(div + bar)").is_err()); > assert!(parse("::slotted(div) + foo").is_err()); > assert!(parse("div ::slotted(div)").is_ok()); >@@ -2902,17 +2840,17 @@ pub mod tests { > } > > #[test] > fn test_universal() { > let selector = &parse_ns( > "*|*::before", > &DummyParser::default_with_namespace(DummyAtom::from("https://mozilla.org")), > ).unwrap() >- .0[0]; >+ .0[0]; > assert!(selector.is_universal()); > } > > #[test] > fn test_empty_pseudo_iter() { > let selector = &parse("::before").unwrap().0[0]; > assert!(selector.is_universal()); > let mut iter = selector.iter(); >diff --git a/servo/components/servo_arc/lib.rs b/servo/components/servo_arc/lib.rs >index 3e6cd65e85da..9163895c606f 100644 >--- a/servo/components/servo_arc/lib.rs >+++ b/servo/components/servo_arc/lib.rs >@@ -27,32 +27,32 @@ extern crate nodrop; > #[cfg(feature = "servo")] > extern crate serde; > extern crate stable_deref_trait; > > use nodrop::NoDrop; > #[cfg(feature = "servo")] > use serde::{Deserialize, Serialize}; > use stable_deref_trait::{CloneStableDeref, StableDeref}; >-use std::{isize, usize}; > use std::borrow; > use std::cmp::Ordering; > use std::convert::From; > use std::fmt; > use std::hash::{Hash, Hasher}; > use std::iter::{ExactSizeIterator, Iterator}; > use std::marker::PhantomData; > use std::mem; > use std::ops::{Deref, DerefMut}; > use std::os::raw::c_void; > use std::process; > use std::ptr; > use std::slice; > use std::sync::atomic; > use std::sync::atomic::Ordering::{Acquire, Relaxed, Release}; >+use std::{isize, usize}; > > // Private macro to get the offset of a struct field in bytes from the address of the struct. > macro_rules! offset_of { > ($container:path, $field:ident) => {{ > // Make sure the field actually exists. This line ensures that a compile-time error is > // generated if $field is accessed through a Deref impl. > let $container { $field: _, .. }; > >@@ -1106,21 +1106,21 @@ impl<A: 'static, B: 'static> Drop for ArcUnion<A, B> { > impl<A: fmt::Debug, B: fmt::Debug> fmt::Debug for ArcUnion<A, B> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > fmt::Debug::fmt(&self.borrow(), f) > } > } > > #[cfg(test)] > mod tests { >+ use super::{Arc, HeaderWithLength, ThinArc}; > use std::clone::Clone; > use std::ops::Drop; > use std::sync::atomic; > use std::sync::atomic::Ordering::{Acquire, SeqCst}; >- use super::{Arc, HeaderWithLength, ThinArc}; > > #[derive(PartialEq)] > struct Canary(*mut atomic::AtomicUsize); > > impl Drop for Canary { > fn drop(&mut self) { > unsafe { > (*self.0).fetch_add(1, SeqCst); >diff --git a/servo/components/size_of_test/lib.rs b/servo/components/size_of_test/lib.rs >index fdd2cd62ec9e..f190c24599de 100644 >--- a/servo/components/size_of_test/lib.rs >+++ b/servo/components/size_of_test/lib.rs >@@ -8,21 +8,27 @@ macro_rules! size_of_test { > #[test] > fn $testname() { > let new = ::std::mem::size_of::<$t>(); > let old = $expected_size; > if new < old { > panic!( > "Your changes have decreased the stack size of {} from {} to {}. \ > Good work! Please update the expected size in {}.", >- stringify!($t), old, new, file!() >+ stringify!($t), >+ old, >+ new, >+ file!() > ) > } else if new > old { > panic!( > "Your changes have increased the stack size of {} from {} to {}. \ > Please consider choosing a design which avoids this increase. \ > If you feel that the increase is necessary, update the size in {}.", >- stringify!($t), old, new, file!() >+ stringify!($t), >+ old, >+ new, >+ file!() > ) > } > } >- } >+ }; > } >diff --git a/servo/components/style/animation.rs b/servo/components/style/animation.rs >index 2d421ce06a93..cd2bd8fd785b 100644 >--- a/servo/components/style/animation.rs >+++ b/servo/components/style/animation.rs >@@ -1,34 +1,34 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! CSS transitions and animations. > >-use Atom; > use bezier::Bezier; > use context::SharedStyleContext; > use dom::{OpaqueNode, TElement}; > use font_metrics::FontMetricsProvider; >-use properties::{self, CascadeMode, ComputedValues, LonghandId}; > use properties::animated_properties::AnimatedProperty; > use properties::longhands::animation_direction::computed_value::single_value::T as AnimationDirection; > use properties::longhands::animation_play_state::computed_value::single_value::T as AnimationPlayState; >+use properties::{self, CascadeMode, ComputedValues, LonghandId}; > use rule_tree::CascadeLevel; > use servo_arc::Arc; > use std::fmt; > use std::sync::mpsc::Sender; > use stylesheets::keyframes_rule::{KeyframesAnimation, KeyframesStep, KeyframesStepValue}; > use timer::Timer; >-use values::computed::Time; > use values::computed::box_::TransitionProperty; > use values::computed::transform::TimingFunction; >+use values::computed::Time; > use values::generics::box_::AnimationIterationCount; > use values::generics::transform::{StepPosition, TimingFunction as GenericTimingFunction}; >+use Atom; > > /// This structure represents a keyframes animation current iteration state. > /// > /// If the iteration count is infinite, there's no other state, otherwise we > /// have to keep track the current iteration and the max iteration count. > #[derive(Clone, Debug)] > pub enum KeyframesIterationState { > /// Infinite iterations, so no need to track a state. >@@ -85,17 +85,17 @@ impl KeyframesAnimationState { > pub fn tick(&mut self) -> bool { > debug!("KeyframesAnimationState::tick"); > debug_assert!(!self.expired); > > self.started_at += self.duration + self.delay; > match self.running_state { > // If it's paused, don't update direction or iteration count. > KeyframesRunningState::Paused(_) => return true, >- KeyframesRunningState::Running => {}, >+ KeyframesRunningState::Running => {} > } > > if let KeyframesIterationState::Finite(ref mut current, ref max) = self.iteration_state { > *current += 1.0; > // NB: This prevent us from updating the direction, which might be > // needed for the correct handling of animation-fill-mode. > if *current >= *max { > return false; >@@ -105,18 +105,18 @@ impl KeyframesAnimationState { > // Update the next iteration direction if applicable. > match self.direction { > AnimationDirection::Alternate | AnimationDirection::AlternateReverse => { > self.current_direction = match self.current_direction { > AnimationDirection::Normal => AnimationDirection::Reverse, > AnimationDirection::Reverse => AnimationDirection::Normal, > _ => unreachable!(), > }; >- }, >- _ => {}, >+ } >+ _ => {} > } > > true > } > > /// Updates the appropiate state from other animation. > /// > /// This happens when an animation is re-submitted to layout, presumably >@@ -147,33 +147,33 @@ impl KeyframesAnimationState { > // restore it. > // > // If the animation keeps paused, keep the old value. > // > // If we're pausing the animation, compute the progress value. > match (&mut self.running_state, old_running_state) { > (&mut Running, Paused(progress)) => { > new_started_at = timer.seconds() - (self.duration * progress) >- }, >+ } > (&mut Paused(ref mut new), Paused(old)) => *new = old, > (&mut Paused(ref mut progress), Running) => { > *progress = (timer.seconds() - old_started_at) / old_duration >- }, >- _ => {}, >+ } >+ _ => {} > } > > // Don't update the iteration count, just the iteration limit. > // TODO: see how changing the limit affects rendering in other browsers. > // We might need to keep the iteration count even when it's infinite. > match (&mut self.iteration_state, old_iteration_state) { > ( > &mut KeyframesIterationState::Finite(ref mut iters, _), > KeyframesIterationState::Finite(old_iters, _), > ) => *iters = old_iters, >- _ => {}, >+ _ => {} > } > > self.current_direction = old_direction; > self.started_at = new_started_at; > } > > #[inline] > fn is_paused(&self) -> bool { >@@ -208,17 +208,22 @@ pub enum Animation { > /// the f64 field is the start time as returned by `time::precise_time_s()`. > /// > /// The `bool` field is werther this animation should no longer run. > Transition(OpaqueNode, f64, AnimationFrame, bool), > /// A keyframes animation is identified by a name, and can have a > /// node-dependent state (i.e. iteration count, etc.). > /// > /// TODO(emilio): The animation object could be refcounted. >- Keyframes(OpaqueNode, KeyframesAnimation, Atom, KeyframesAnimationState), >+ Keyframes( >+ OpaqueNode, >+ KeyframesAnimation, >+ Atom, >+ KeyframesAnimationState, >+ ), > } > > impl Animation { > /// Mark this animation as expired. > #[inline] > pub fn mark_as_expired(&mut self) { > debug_assert!(!self.is_expired()); > match *self { >@@ -299,44 +304,42 @@ impl PropertyAnimation { > ) -> Vec<PropertyAnimation> { > let mut result = vec![]; > let box_style = new_style.get_box(); > let transition_property = box_style.transition_property_at(transition_index); > let timing_function = box_style.transition_timing_function_mod(transition_index); > let duration = box_style.transition_duration_mod(transition_index); > > match transition_property { >- TransitionProperty::Custom(..) | >- TransitionProperty::Unsupported(..) => result, >+ TransitionProperty::Custom(..) | TransitionProperty::Unsupported(..) => result, > TransitionProperty::Shorthand(ref shorthand_id) => shorthand_id > .longhands() > .filter_map(|longhand| { > PropertyAnimation::from_longhand( > longhand, > timing_function, > duration, > old_style, > new_style, > ) >- }) >- .collect(), >+ }).collect(), > TransitionProperty::Longhand(longhand_id) => { > let animation = PropertyAnimation::from_longhand( > longhand_id, > timing_function, > duration, > old_style, > new_style, > ); > > if let Some(animation) = animation { > result.push(animation); > } > result >- }, >+ } > } > } > > fn from_longhand( > longhand: LonghandId, > timing_function: TimingFunction, > duration: Time, > old_style: &ComputedValues, >@@ -358,43 +361,43 @@ impl PropertyAnimation { > } > > /// Update the given animation at a given point of progress. > pub fn update(&self, style: &mut ComputedValues, time: f64) { > let epsilon = 1. / (200. * (self.duration.seconds() as f64)); > let progress = match self.timing_function { > GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => { > Bezier::new(x1, y1, x2, y2).solve(time, epsilon) >- }, >+ } > GenericTimingFunction::Steps(steps, StepPosition::Start) => { > (time * (steps as f64)).ceil() / (steps as f64) >- }, >+ } > GenericTimingFunction::Steps(steps, StepPosition::End) => { > (time * (steps as f64)).floor() / (steps as f64) >- }, >+ } > GenericTimingFunction::Frames(frames) => { > // https://drafts.csswg.org/css-timing/#frames-timing-functions > let mut out = (time * (frames as f64)).floor() / ((frames - 1) as f64); > if out > 1.0 { > // FIXME: Basically, during the animation sampling process, the input progress > // should be in the range of [0, 1]. However, |time| is not accurate enough > // here, which means |time| could be larger than 1.0 in the last animation > // frame. (It should be equal to 1.0 exactly.) This makes the output of frames > // timing function jumps to the next frame/level. > // However, this solution is still not correct because |time| is possible > // outside the range of [0, 1] after introducing Web Animations. We should fix > // this problem when implementing web animations. > out = 1.0; > } > out >- }, >+ } > GenericTimingFunction::Keyword(keyword) => { > let (x1, x2, y1, y2) = keyword.to_bezier(); > Bezier::new(x1, x2, y1, y2).solve(time, epsilon) >- }, >+ } > }; > > self.property.update(style, progress); > } > > #[inline] > fn does_animate(&self) -> bool { > self.property.does_animate() && self.duration.seconds() != 0.0 >@@ -450,18 +453,17 @@ pub fn start_transitions_if_applicable( > .send(Animation::Transition( > opaque_node, > start_time, > AnimationFrame { > duration: box_style.transition_duration_mod(i).seconds() as f64, > property_animation: property_animation, > }, > /* is_expired = */ false, >- )) >- .unwrap(); >+ )).unwrap(); > > had_animations = true; > } > } > > had_animations > } > >@@ -500,24 +502,26 @@ where > /* pseudo = */ None, > previous_style.rules(), > &context.guards, > iter, > Some(previous_style), > Some(previous_style), > Some(previous_style), > font_metrics_provider, >- CascadeMode::Unvisited { visited_rules: None }, >+ CascadeMode::Unvisited { >+ visited_rules: None, >+ }, > context.quirks_mode(), > /* rule_cache = */ None, > &mut Default::default(), > /* element = */ None, > ); > computed >- }, >+ } > } > } > > /// Triggers animations for a given node looking at the animation property > /// values. > pub fn maybe_start_animations<E>( > element: E, > context: &SharedStyleContext, >@@ -564,20 +568,20 @@ where > AnimationIterationCount::Number(n) => KeyframesIterationState::Finite(0.0, n), > }; > > let animation_direction = box_style.animation_direction_mod(i); > > let initial_direction = match animation_direction { > AnimationDirection::Normal | AnimationDirection::Alternate => { > AnimationDirection::Normal >- }, >+ } > AnimationDirection::Reverse | AnimationDirection::AlternateReverse => { > AnimationDirection::Reverse >- }, >+ } > }; > > let running_state = match box_style.animation_play_state_mod(i) { > AnimationPlayState::Paused => KeyframesRunningState::Paused(0.), > AnimationPlayState::Running => KeyframesRunningState::Running, > }; > > new_animations_sender >@@ -591,18 +595,17 @@ where > delay: delay as f64, > iteration_state: iteration_state, > running_state: running_state, > direction: animation_direction, > current_direction: initial_direction, > expired: false, > cascade_style: new_style.clone(), > }, >- )) >- .unwrap(); >+ )).unwrap(); > had_animations = true; > } > } > > had_animations > } > > /// Updates a given computed style for a given animation frame. Returns a bool >@@ -646,17 +649,17 @@ pub fn update_style_for_animation<E>( > debug!("update_style_for_animation: transition found"); > let now = context.timer.seconds(); > let mut new_style = (*style).clone(); > let updated_style = > update_style_for_animation_frame(&mut new_style, now, start_time, frame); > if updated_style { > *style = new_style > } >- }, >+ } > Animation::Keyframes(_, ref animation, ref name, ref state) => { > debug!( > "update_style_for_animation: animation found: \"{}\", {:?}", > name, state > ); > let duration = state.duration; > let started_at = state.started_at; > >@@ -675,17 +678,17 @@ pub fn update_style_for_animation<E>( > let index = match maybe_index { > Some(index) => index, > None => { > warn!( > "update_style_for_animation: Animation {:?} not found in style", > name > ); > return; >- }, >+ } > }; > > let total_duration = style.get_box().animation_duration_mod(index).seconds() as f64; > if total_duration == 0. { > debug!( > "update_style_for_animation: zero duration for animation {:?}", > name > ); >@@ -714,65 +717,64 @@ pub fn update_style_for_animation<E>( > target_keyframe_position = animation > .steps > .iter() > .position(|step| total_progress as f32 <= step.start_percentage.0); > > last_keyframe_position = target_keyframe_position > .and_then(|pos| if pos != 0 { Some(pos - 1) } else { None }) > .unwrap_or(0); >- }, >+ } > AnimationDirection::Reverse => { > target_keyframe_position = animation > .steps > .iter() > .rev() > .position(|step| total_progress as f32 <= 1. - step.start_percentage.0) > .map(|pos| animation.steps.len() - pos - 1); > > last_keyframe_position = target_keyframe_position > .and_then(|pos| { > if pos != animation.steps.len() - 1 { > Some(pos + 1) > } else { > None > } >- }) >- .unwrap_or(animation.steps.len() - 1); >- }, >+ }).unwrap_or(animation.steps.len() - 1); >+ } > _ => unreachable!(), > } > > debug!( > "update_style_for_animation: keyframe from {:?} to {:?}", > last_keyframe_position, target_keyframe_position > ); > > let target_keyframe = match target_keyframe_position { > Some(target) => &animation.steps[target], > None => { > warn!("update_style_for_animation: No current keyframe found for animation \"{}\" at progress {}", > name, total_progress); > return; >- }, >+ } > }; > > let last_keyframe = &animation.steps[last_keyframe_position]; > > let relative_timespan = > (target_keyframe.start_percentage.0 - last_keyframe.start_percentage.0).abs(); > let relative_duration = relative_timespan as f64 * duration; > let last_keyframe_ended_at = match state.current_direction { > AnimationDirection::Normal => { > state.started_at + (total_duration * last_keyframe.start_percentage.0 as f64) >- }, >+ } > AnimationDirection::Reverse => { >- state.started_at + >- (total_duration * (1. - last_keyframe.start_percentage.0 as f64)) >- }, >+ state.started_at >+ + (total_duration * (1. - last_keyframe.start_percentage.0 as f64)) >+ } > _ => unreachable!(), > }; > let relative_progress = (now - last_keyframe_ended_at) / relative_duration; > > // TODO: How could we optimise it? Is it such a big deal? > let from_style = compute_style_for_animation_step::<E>( > context, > last_keyframe, >@@ -816,32 +818,32 @@ pub fn update_style_for_animation<E>( > match animation { > Some(property_animation) => { > debug!( > "update_style_for_animation: got property animation for prop {:?}", > property > ); > debug!("update_style_for_animation: {:?}", property_animation); > property_animation.update(Arc::make_mut(&mut new_style), relative_progress); >- }, >+ } > None => { > debug!( > "update_style_for_animation: property animation {:?} not animating", > property > ); >- }, >+ } > } > } > > debug!( > "update_style_for_animation: got style change in animation \"{}\"", > name > ); > *style = new_style; >- }, >+ } > } > } > > /// Update the style in the node when it finishes. > #[cfg(feature = "servo")] > pub fn complete_expired_transitions( > node: OpaqueNode, > style: &mut Arc<ComputedValues>, >diff --git a/servo/components/style/applicable_declarations.rs b/servo/components/style/applicable_declarations.rs >index a1476917fcbd..95a6f947ac60 100644 >--- a/servo/components/style/applicable_declarations.rs >+++ b/servo/components/style/applicable_declarations.rs >@@ -33,17 +33,18 @@ const SOURCE_ORDER_MASK: u32 = SOURCE_ORDER_MAX << SOURCE_ORDER_SHIFT; > > /// We store up-to-15 shadow order levels. > /// > /// You'd need an element slotted across 16 components with ::slotted rules to > /// trigger this as of this writing, which looks... Unlikely. > const SHADOW_CASCADE_ORDER_SHIFT: usize = SOURCE_ORDER_BITS; > const SHADOW_CASCADE_ORDER_BITS: usize = 4; > const SHADOW_CASCADE_ORDER_MAX: u8 = (1 << SHADOW_CASCADE_ORDER_BITS) - 1; >-const SHADOW_CASCADE_ORDER_MASK: u32 = (SHADOW_CASCADE_ORDER_MAX as u32) << SHADOW_CASCADE_ORDER_SHIFT; >+const SHADOW_CASCADE_ORDER_MASK: u32 = >+ (SHADOW_CASCADE_ORDER_MAX as u32) << SHADOW_CASCADE_ORDER_SHIFT; > > const CASCADE_LEVEL_SHIFT: usize = SOURCE_ORDER_BITS + SHADOW_CASCADE_ORDER_BITS; > const CASCADE_LEVEL_BITS: usize = 4; > const CASCADE_LEVEL_MAX: u8 = (1 << CASCADE_LEVEL_BITS) - 1; > const CASCADE_LEVEL_MASK: u32 = (CASCADE_LEVEL_MAX as u32) << CASCADE_LEVEL_SHIFT; > > /// Stores the source order of a block, the cascade level it belongs to, and the > /// counter needed to handle Shadow DOM cascade order properly. >@@ -56,17 +57,18 @@ impl ApplicableDeclarationBits { > cascade_level: CascadeLevel, > shadow_cascade_order: ShadowCascadeOrder, > ) -> Self { > debug_assert!( > cascade_level as u8 <= CASCADE_LEVEL_MAX, > "Gotta find more bits!" > ); > let mut bits = ::std::cmp::min(source_order, SOURCE_ORDER_MAX); >- bits |= ((shadow_cascade_order & SHADOW_CASCADE_ORDER_MAX) as u32) << SHADOW_CASCADE_ORDER_SHIFT; >+ bits |= ((shadow_cascade_order & SHADOW_CASCADE_ORDER_MAX) as u32) >+ << SHADOW_CASCADE_ORDER_SHIFT; > bits |= (cascade_level as u8 as u32) << CASCADE_LEVEL_SHIFT; > ApplicableDeclarationBits(bits) > } > > fn source_order(&self) -> u32 { > (self.0 & SOURCE_ORDER_MASK) >> SOURCE_ORDER_SHIFT > } > >diff --git a/servo/components/style/attr.rs b/servo/components/style/attr.rs >index 5f335472f324..41b7800071ab 100644 >--- a/servo/components/style/attr.rs >+++ b/servo/components/style/attr.rs >@@ -1,31 +1,31 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Parsed representations of [DOM attributes][attr]. > //! > //! [attr]: https://dom.spec.whatwg.org/#interface-attr > >-use {Atom, LocalName, Namespace, Prefix}; > use app_units::Au; > use cssparser::{self, Color, RGBA}; > use euclid::num::Zero; > use num_traits::ToPrimitive; > use properties::PropertyDeclarationBlock; > use selectors::attr::AttrSelectorOperation; > use servo_arc::Arc; > use servo_url::ServoUrl; > use shared_lock::Locked; > use std::str::FromStr; >+use str::str_join; > use str::{read_exponent, read_fraction, HTML_SPACE_CHARACTERS}; > use str::{read_numbers, split_commas, split_html_space_chars}; >-use str::str_join; > use values::specified::Length; >+use {Atom, LocalName, Namespace, Prefix}; > > // Duplicated from script::dom::values. > const UNSIGNED_LONG_MAX: u32 = 2147483647; > > #[derive(Clone, Copy, Debug, PartialEq)] > #[cfg_attr(feature = "servo", derive(MallocSizeOf))] > pub enum LengthOrPercentageOrAuto { > Auto, >@@ -78,21 +78,21 @@ fn do_parse_integer<T: Iterator<Item = char>>(input: T) -> Result<i64, ()> { > .skip_while(|c| HTML_SPACE_CHARACTERS.iter().any(|s| s == c)) > .peekable(); > > let sign = match input.peek() { > None => return Err(()), > Some(&'-') => { > input.next(); > -1 >- }, >+ } > Some(&'+') => { > input.next(); > 1 >- }, >+ } > Some(_) => 1, > }; > > let (value, _) = read_numbers(input); > > value.and_then(|value| value.checked_mul(sign)).ok_or(()) > } > >@@ -114,21 +114,21 @@ pub fn parse_double(string: &str) -> Result<f64, ()> { > let trimmed = string.trim_matches(HTML_SPACE_CHARACTERS); > let mut input = trimmed.chars().peekable(); > > let (value, divisor, chars_skipped) = match input.peek() { > None => return Err(()), > Some(&'-') => { > input.next(); > (-1f64, -1f64, 1) >- }, >+ } > Some(&'+') => { > input.next(); > (1f64, 1f64, 1) >- }, >+ } > _ => (1f64, 1f64, 0), > }; > > let (value, value_digits) = if let Some(&'.') = input.peek() { > (0f64, 0) > } else { > let (read_val, read_digits) = read_numbers(input); > ( >@@ -153,25 +153,25 @@ pub fn parse_double(string: &str) -> Result<f64, ()> { > value *= 10f64.powi(exp) > }; > > Ok(value) > } > > impl AttrValue { > pub fn from_serialized_tokenlist(tokens: String) -> AttrValue { >- let atoms = split_html_space_chars(&tokens).map(Atom::from).fold( >- vec![], >- |mut acc, atom| { >- if !acc.contains(&atom) { >- acc.push(atom) >- } >- acc >- }, >- ); >+ let atoms = >+ split_html_space_chars(&tokens) >+ .map(Atom::from) >+ .fold(vec![], |mut acc, atom| { >+ if !acc.contains(&atom) { >+ acc.push(atom) >+ } >+ acc >+ }); > AttrValue::TokenList(tokens, atoms) > } > > pub fn from_comma_separated_tokenlist(tokens: String) -> AttrValue { > let atoms = split_commas(&tokens) > .map(Atom::from) > .fold(vec![], |mut acc, atom| { > if !acc.contains(&atom) { >@@ -374,26 +374,26 @@ impl AttrValue { > } > } > > impl ::std::ops::Deref for AttrValue { > type Target = str; > > fn deref(&self) -> &str { > match *self { >- AttrValue::String(ref value) | >- AttrValue::TokenList(ref value, _) | >- AttrValue::UInt(ref value, _) | >- AttrValue::Double(ref value, _) | >- AttrValue::Length(ref value, _) | >- AttrValue::Color(ref value, _) | >- AttrValue::Int(ref value, _) | >- AttrValue::ResolvedUrl(ref value, _) | >- AttrValue::Declaration(ref value, _) | >- AttrValue::Dimension(ref value, _) => &value, >+ AttrValue::String(ref value) >+ | AttrValue::TokenList(ref value, _) >+ | AttrValue::UInt(ref value, _) >+ | AttrValue::Double(ref value, _) >+ | AttrValue::Length(ref value, _) >+ | AttrValue::Color(ref value, _) >+ | AttrValue::Int(ref value, _) >+ | AttrValue::ResolvedUrl(ref value, _) >+ | AttrValue::Declaration(ref value, _) >+ | AttrValue::Dimension(ref value, _) => &value, > AttrValue::Atom(ref value) => &value, > } > } > } > > impl PartialEq<Atom> for AttrValue { > fn eq(&self, other: &Atom) -> bool { > match *self { >@@ -530,17 +530,17 @@ pub fn parse_legacy_color(mut input: &str) -> Result<RGBA, ()> { > fn hex_string(string: &[u8]) -> Result<u8, ()> { > match string.len() { > 0 => Err(()), > 1 => hex(string[0] as char), > _ => { > let upper = hex(string[0] as char)?; > let lower = hex(string[1] as char)?; > Ok((upper << 4) | lower) >- }, >+ } > } > } > } > > /// Parses a [dimension value][dim]. If unparseable, `Auto` is returned. > /// > /// [dim]: https://html.spec.whatwg.org/multipage/#rules-for-parsing-dimension-values > // TODO: this function can be rewritten to return Result<LengthOrPercentage, _> >@@ -557,17 +557,17 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { > > // Step 5 > if value.starts_with('+') { > value = &value[1..] > } > > // Steps 6 & 7 > match value.chars().nth(0) { >- Some('0'...'9') => {}, >+ Some('0'...'9') => {} > _ => return LengthOrPercentageOrAuto::Auto, > } > > // Steps 8 to 13 > // We trim the string length to the minimum of: > // 1. the end of the string > // 2. the first occurence of a '%' (U+0025 PERCENT SIGN) > // 3. the second occurrence of a '.' (U+002E FULL STOP) >@@ -577,25 +577,25 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto { > let (mut found_full_stop, mut found_percent) = (false, false); > for (i, ch) in value.chars().enumerate() { > match ch { > '0'...'9' => continue, > '%' => { > found_percent = true; > end_index = i; > break; >- }, >+ } > '.' if !found_full_stop => { > found_full_stop = true; > continue; >- }, >+ } > _ => { > end_index = i; > break; >- }, >+ } > } > } > value = &value[..end_index]; > > if found_percent { > let result: Result<f32, _> = FromStr::from_str(value); > match result { > Ok(number) => return LengthOrPercentageOrAuto::Percentage((number as f32) / 100.0), >diff --git a/servo/components/style/author_styles.rs b/servo/components/style/author_styles.rs >index e8ec621bd92e..837569078c08 100644 >--- a/servo/components/style/author_styles.rs >+++ b/servo/components/style/author_styles.rs >@@ -55,25 +55,27 @@ where > &mut self, > device: &Device, > quirks_mode: QuirksMode, > guard: &SharedRwLockReadGuard, > ) where > E: TElement, > S: ToMediaListKey, > { >- let flusher = self.stylesheets >+ let flusher = self >+ .stylesheets > .flush::<E>(/* host = */ None, /* snapshot_map = */ None); > > if flusher.sheets.dirty() { > self.quirks_mode = quirks_mode; > } > > // Ignore OOM. >- let _ = self.data >+ let _ = self >+ .data > .rebuild(device, quirks_mode, flusher.sheets, guard); > } > } > > #[cfg(feature = "gecko")] > unsafe impl HasFFI for AuthorStyles<::gecko::data::GeckoStyleSheet> { > type FFIType = ::gecko_bindings::bindings::RawServoAuthorStyles; > } >diff --git a/servo/components/style/bloom.rs b/servo/components/style/bloom.rs >index 613cbde49992..3f7cfc1626e0 100644 >--- a/servo/components/style/bloom.rs >+++ b/servo/components/style/bloom.rs >@@ -277,17 +277,17 @@ impl<E: TElement> StyleBloom<E> { > } > > let traversal_parent = match element.traversal_parent() { > Some(parent) => parent, > None => { > // Yay, another easy case. > self.clear(); > return; >- }, >+ } > }; > > if self.current_parent() == Some(traversal_parent) { > // Ta da, cache hit, we're all done. > return; > } > > if element_depth == 0 { >@@ -359,17 +359,17 @@ impl<E: TElement> StyleBloom<E> { > Some(parent) => parent, > None => { > debug_assert!(self.elements.is_empty()); > if cfg!(feature = "gecko") { > break; > } else { > panic!("should have found a common ancestor"); > } >- }, >+ } > } > } > > // Now the parents match, so insert the stack of elements we have been > // collecting so far. > for parent in parents_to_insert.drain().rev() { > self.push(parent); > } >diff --git a/servo/components/style/build.rs b/servo/components/style/build.rs >index 8de16176c346..82695d6d2a63 100644 >--- a/servo/components/style/build.rs >+++ b/servo/components/style/build.rs >@@ -75,18 +75,18 @@ lazy_static! { > } > > fn generate_properties() { > for entry in WalkDir::new("properties") { > let entry = entry.unwrap(); > match entry.path().extension().and_then(|e| e.to_str()) { > Some("mako") | Some("rs") | Some("py") | Some("zip") => { > println!("cargo:rerun-if-changed={}", entry.path().display()); >- }, >- _ => {}, >+ } >+ _ => {} > } > } > > let script = Path::new(&env::var_os("CARGO_MANIFEST_DIR").unwrap()) > .join("properties") > .join("build.py"); > let product = if cfg!(feature = "gecko") { > "gecko" >diff --git a/servo/components/style/build_gecko.rs b/servo/components/style/build_gecko.rs >index 8387f6513a68..7774265fc071 100644 >--- a/servo/components/style/build_gecko.rs >+++ b/servo/components/style/build_gecko.rs >@@ -9,30 +9,30 @@ mod common { > lazy_static! { > pub static ref OUTDIR_PATH: PathBuf = > PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("gecko"); > } > } > > #[cfg(feature = "bindgen")] > mod bindings { >+ use super::super::PYTHON; >+ use super::common::*; > use bindgen::{Builder, CodegenConfig}; > use regex::Regex; > use std::cmp; > use std::collections::{HashMap, HashSet}; > use std::env; > use std::fs::{self, File}; > use std::io::{Read, Write}; > use std::path::{Path, PathBuf}; > use std::process::{exit, Command}; > use std::slice; > use std::sync::Mutex; > use std::time::SystemTime; >- use super::common::*; >- use super::super::PYTHON; > use toml; > use toml::value::Table; > > const STRUCTS_FILE: &'static str = "structs.rs"; > const BINDINGS_FILE: &'static str = "bindings.rs"; > > fn read_config(path: &PathBuf) -> Table { > println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); >@@ -278,17 +278,17 @@ mod bindings { > let result = builder.generate(); > let mut result = match result { > Ok(bindings) => bindings.to_string(), > Err(_) => { > panic!( > "Failed to generate bindings, flags: {:?}", > command_line_opts > ); >- }, >+ } > }; > > for fixup in fixups.iter() { > result = Regex::new(&fixup.pat) > .unwrap() > .replace_all(&result, &*fixup.rep) > .into_owned() > .into(); >@@ -317,23 +317,21 @@ mod bindings { > .lines() > .map(|line| line.trim()) > .filter(|line| !line.is_empty()) > .map(|line| { > re.captures(&line) > .expect(&format!( > "Unrecognized line in ServoArcTypeList.h: '{}'", > line >- )) >- .get(1) >+ )).get(1) > .unwrap() > .as_str() > .to_string() >- }) >- .collect() >+ }).collect() > } > > struct BuilderWithConfig<'a> { > builder: Builder, > config: &'a Table, > used_keys: HashSet<&'static str>, > } > impl<'a> BuilderWithConfig<'a> { >@@ -435,18 +433,17 @@ mod bindings { > rep: format!("::gecko_bindings::structs::{}", gecko_name), > }); > builder.blacklist_type(gecko).raw_line(format!( > "pub type {0}{2} = {1}{2};", > gecko_name, > servo, > if generic { "<T>" } else { "" } > )) >- }) >- .get_builder(); >+ }).get_builder(); > write_binding_file(builder, STRUCTS_FILE, &fixups); > } > > fn setup_logging() -> bool { > use log; > > struct BuildLogger { > file: Option<Mutex<fs::File>>, >@@ -555,18 +552,17 @@ mod bindings { > .handle_str_items("servo-borrow-types", |b, ty| b.mutable_borrowed_type(ty)) > .get_builder(); > for ty in get_arc_types().iter() { > builder = builder > .blacklist_type(format!("{}Strong", ty)) > .raw_line(format!( > "pub type {0}Strong = ::gecko_bindings::sugar::ownership::Strong<{0}>;", > ty >- )) >- .borrowed_type(ty) >+ )).borrowed_type(ty) > .zero_size_type(ty, &structs_types); > } > write_binding_file(builder, BINDINGS_FILE, &fixups); > } > > fn generate_atoms() { > let script = PathBuf::from(env::var_os("CARGO_MANIFEST_DIR").unwrap()) > .join("gecko") >@@ -606,19 +602,19 @@ mod bindings { > for path in ADDED_PATHS.lock().unwrap().iter() { > println!("cargo:rerun-if-changed={}", path.to_str().unwrap()); > } > } > } > > #[cfg(not(feature = "bindgen"))] > mod bindings { >+ use super::common::*; >+ use std::path::{Path, PathBuf}; > use std::{env, fs, io}; >- use std::path::{Path, PathBuf}; >- use super::common::*; > > /// Copy contents of one directory into another. > /// It currently only does a shallow copy. > fn copy_dir<P, Q, F>(from: P, to: Q, callback: F) -> io::Result<()> > where > P: AsRef<Path>, > Q: AsRef<Path>, > F: Fn(&Path), >diff --git a/servo/components/style/context.rs b/servo/components/style/context.rs >index 16bba2a863f4..8e3e05b53559 100644 >--- a/servo/components/style/context.rs >+++ b/servo/components/style/context.rs >@@ -4,47 +4,47 @@ > > //! The context within which style is calculated. > > #[cfg(feature = "servo")] > use animation::Animation; > use app_units::Au; > use bloom::StyleBloom; > use data::{EagerPseudoStyles, ElementData}; >-use dom::{SendElement, TElement}; > #[cfg(feature = "servo")] > use dom::OpaqueNode; >+use dom::{SendElement, TElement}; > use euclid::Size2D; > use euclid::TypedScale; > use font_metrics::FontMetricsProvider; > use fxhash::FxHashMap; > #[cfg(feature = "gecko")] > use gecko_bindings::structs; > use parallel::{STACK_SAFETY_MARGIN_KB, STYLE_THREAD_STACK_SIZE_KB}; > #[cfg(feature = "servo")] > use parking_lot::RwLock; > use properties::ComputedValues; > #[cfg(feature = "servo")] > use properties::PropertyId; > use rule_cache::RuleCache; > use rule_tree::StrongRuleNode; > use selector_parser::{SnapshotMap, EAGER_PSEUDO_COUNT}; >-use selectors::NthIndexCache; > use selectors::matching::ElementSelectorFlags; >+use selectors::NthIndexCache; > use servo_arc::Arc; > #[cfg(feature = "servo")] > use servo_atoms::Atom; > use shared_lock::StylesheetGuards; > use sharing::StyleSharingCache; > use std::fmt; > use std::ops; > #[cfg(feature = "servo")] >-use std::sync::Mutex; >-#[cfg(feature = "servo")] > use std::sync::mpsc::Sender; >+#[cfg(feature = "servo")] >+use std::sync::Mutex; > use style_traits::CSSPixel; > use style_traits::DevicePixel; > #[cfg(feature = "servo")] > use style_traits::SpeculativePainter; > use stylist::Stylist; > use thread_state::{self, ThreadState}; > use time; > use timer::Timer; >@@ -523,21 +523,21 @@ impl<E: TElement> SequentialTask<E> { > Unused(_) => unreachable!(), > #[cfg(feature = "gecko")] > UpdateAnimations { > el, > before_change_style, > tasks, > } => { > el.update_animations(before_change_style, tasks); >- }, >+ } > #[cfg(feature = "gecko")] > PostAnimation { el, tasks } => { > el.process_post_animation(tasks); >- }, >+ } > } > } > > /// Creates a task to update various animation-related state on a given > /// (pseudo-)element. > #[cfg(feature = "gecko")] > pub fn update_animations( > el: E, >diff --git a/servo/components/style/counter_style/mod.rs b/servo/components/style/counter_style/mod.rs >index 2542dee3625a..1b911ea5cf18 100644 >--- a/servo/components/style/counter_style/mod.rs >+++ b/servo/components/style/counter_style/mod.rs >@@ -1,32 +1,32 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! The [`@counter-style`][counter-style] at-rule. > //! > //! [counter-style]: https://drafts.csswg.org/css-counter-styles/ > >-use Atom; > use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser}; > use cssparser::{CowRcStr, Parser, SourceLocation, Token}; > use error_reporting::ContextualParseError; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use std::mem; > use std::num::Wrapping; > use std::ops::Range; > use str::CssStringWriter; > use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError}; > use style_traits::{StyleParseErrorKind, ToCss}; >-use values::CustomIdent; > use values::specified::Integer; >+use values::CustomIdent; >+use Atom; > > /// Parse a counter style name reference. > /// > /// This allows the reserved counter style names "decimal" and "disc". > pub fn parse_counter_style_name<'i, 't>( > input: &mut Parser<'i, 't>, > ) -> Result<CustomIdent, ParseError<'i>> { > macro_rules! predefined { >@@ -86,52 +86,52 @@ pub fn parse_counter_style_body<'i, 't>( > context: context, > rule: &mut rule, > }; > let mut iter = DeclarationListParser::new(input, parser); > while let Some(declaration) = iter.next() { > if let Err((error, slice)) = declaration { > let location = error.location; > let error = ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration( >- slice, >- error, >+ slice, error, > ); > context.log_css_error(location, error) > } > } > } > let error = match *rule.resolved_system() { >- ref system @ System::Cyclic | >- ref system @ System::Fixed { .. } | >- ref system @ System::Symbolic | >- ref system @ System::Alphabetic | >- ref system @ System::Numeric if rule.symbols.is_none() => >+ ref system @ System::Cyclic >+ | ref system @ System::Fixed { .. } >+ | ref system @ System::Symbolic >+ | ref system @ System::Alphabetic >+ | ref system @ System::Numeric >+ if rule.symbols.is_none() => > { > let system = system.to_css_string(); > Some(ContextualParseError::InvalidCounterStyleWithoutSymbols( > system, > )) > } > ref system @ System::Alphabetic | ref system @ System::Numeric > if rule.symbols().unwrap().0.len() < 2 => > { > let system = system.to_css_string(); > Some(ContextualParseError::InvalidCounterStyleNotEnoughSymbols( > system, > )) > } > System::Additive if rule.additive_symbols.is_none() => { > Some(ContextualParseError::InvalidCounterStyleWithoutAdditiveSymbols) >- }, >+ } > System::Extends(_) if rule.symbols.is_some() => { > Some(ContextualParseError::InvalidCounterStyleExtendsWithSymbols) >- }, >+ } > System::Extends(_) if rule.additive_symbols.is_some() => { > Some(ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols) >- }, >+ } > _ => None, > }; > if let Some(error) = error { > context.log_css_error(start, error); > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } else { > Ok(rule) > } >@@ -394,21 +394,21 @@ impl ToCss for System { > System::Additive => dest.write_str("additive"), > System::Fixed { first_symbol_value } => { > if let Some(value) = first_symbol_value { > dest.write_str("fixed ")?; > value.to_css(dest) > } else { > dest.write_str("fixed") > } >- }, >+ } > System::Extends(ref other) => { > dest.write_str("extends ")?; > other.to_css(dest) >- }, >+ } > } > } > } > > /// <https://drafts.csswg.org/css-counter-styles/#typedef-symbol> > #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] > #[derive(Clone, Debug, Eq, PartialEq, ToComputedValue, ToCss)] > pub enum Symbol { >@@ -491,22 +491,23 @@ impl Parse for Ranges { > input > .parse_comma_separated(|input| { > let opt_start = parse_bound(context, input)?; > let opt_end = parse_bound(context, input)?; > if let (CounterBound::Integer(start), CounterBound::Integer(end)) = > (opt_start, opt_end) > { > if start > end { >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::UnspecifiedError) >+ ); > } > } > Ok(opt_start..opt_end) >- }) >- .map(Ranges) >+ }).map(Ranges) > } > } > } > > fn parse_bound<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<CounterBound, ParseError<'i>> { >diff --git a/servo/components/style/custom_properties.rs b/servo/components/style/custom_properties.rs >index d79a27c5c4d8..d0bbf53cba3f 100644 >--- a/servo/components/style/custom_properties.rs >+++ b/servo/components/style/custom_properties.rs >@@ -1,30 +1,30 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Support for [custom properties for cascading variables][custom]. > //! > //! [custom]: https://drafts.csswg.org/css-variables/ > >-use Atom; > use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSerializationType}; > use hash::map::Entry; > use precomputed_hash::PrecomputedHash; > use properties::{CSSWideKeyword, DeclaredValue}; > use selector_map::{PrecomputedHashMap, PrecomputedHashSet}; > use selectors::parser::SelectorParseErrorKind; > use servo_arc::Arc; > use smallvec::SmallVec; > use std::borrow::{Borrow, Cow}; > use std::cmp; > use std::fmt::{self, Write}; > use std::hash::Hash; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; >+use Atom; > > /// A custom property name is just an `Atom`. > /// > /// Note that this does not include the `--` prefix > pub type Name = Atom; > > /// Parse a custom property name. > /// >@@ -113,20 +113,20 @@ where > let OrderedMap { > ref mut index, > ref mut values, > } = *self; > match values.entry(key) { > Entry::Vacant(mut entry) => { > index.push(entry.key().clone()); > entry.insert(value); >- }, >+ } > Entry::Occupied(mut entry) => { > entry.insert(value); >- }, >+ } > } > } > > /// Get a value given its key. > pub fn get(&self, key: &K) -> Option<&V> { > let value = self.values.get(key); > debug_assert_eq!(value.is_some(), self.index.contains(key)); > value >@@ -238,17 +238,18 @@ impl VariableValue { > // In that case, css_*_token_type is nonsensical. > if css.is_empty() { > return; > } > > self.first_token_type.set_if_nothing(css_first_token_type); > // If self.first_token_type was nothing, > // self.last_token_type is also nothing and this will be false: >- if self.last_token_type >+ if self >+ .last_token_type > .needs_separator_when_before(css_first_token_type) > { > self.css.push_str("/**/") > } > self.css.push_str(css); > self.last_token_type = css_last_token_type > } > >@@ -340,17 +341,17 @@ fn parse_declaration_value_block<'i, 't>( > let mut token = match input.next_including_whitespace_and_comments() { > // FIXME: remove clone() when borrows are non-lexical > Ok(token) => token.clone(), > Err(_) => { > return Ok(( > TokenSerializationType::nothing(), > TokenSerializationType::nothing(), > )) >- }, >+ } > }; > let first_token_type = token.serialization_type(); > loop { > macro_rules! nested { > () => { > input.parse_nested_block(|input| { > parse_declaration_value_block( > input, >@@ -373,93 +374,93 @@ fn parse_declaration_value_block<'i, 't>( > if !token_slice.ends_with("*/") { > missing_closing_characters.push_str(if token_slice.ends_with('*') { > "/" > } else { > "*/" > }) > } > token.serialization_type() >- }, >+ } > Token::BadUrl(u) => { > let e = StyleParseErrorKind::BadUrlInDeclarationValueBlock(u); > return Err(input.new_custom_error(e)); >- }, >+ } > Token::BadString(s) => { > let e = StyleParseErrorKind::BadStringInDeclarationValueBlock(s); > return Err(input.new_custom_error(e)); >- }, >+ } > Token::CloseParenthesis => { > let e = StyleParseErrorKind::UnbalancedCloseParenthesisInDeclarationValueBlock; > return Err(input.new_custom_error(e)); >- }, >+ } > Token::CloseSquareBracket => { > let e = StyleParseErrorKind::UnbalancedCloseSquareBracketInDeclarationValueBlock; > return Err(input.new_custom_error(e)); >- }, >+ } > Token::CloseCurlyBracket => { > let e = StyleParseErrorKind::UnbalancedCloseCurlyBracketInDeclarationValueBlock; > return Err(input.new_custom_error(e)); >- }, >+ } > Token::Function(ref name) => { > if name.eq_ignore_ascii_case("var") { > let args_start = input.state(); > input.parse_nested_block(|input| { > parse_var_function(input, references.as_mut().map(|r| &mut **r)) > })?; > input.reset(&args_start); > } > nested!(); > check_closed!(")"); > Token::CloseParenthesis.serialization_type() >- }, >+ } > Token::ParenthesisBlock => { > nested!(); > check_closed!(")"); > Token::CloseParenthesis.serialization_type() >- }, >+ } > Token::CurlyBracketBlock => { > nested!(); > check_closed!("}"); > Token::CloseCurlyBracket.serialization_type() >- }, >+ } > Token::SquareBracketBlock => { > nested!(); > check_closed!("]"); > Token::CloseSquareBracket.serialization_type() >- }, >+ } > Token::QuotedString(_) => { > let token_slice = input.slice_from(token_start); > let quote = &token_slice[..1]; > debug_assert!(matches!(quote, "\"" | "'")); > if !(token_slice.ends_with(quote) && token_slice.len() > 1) { > missing_closing_characters.push_str(quote) > } > token.serialization_type() >- }, >- Token::Ident(ref value) | >- Token::AtKeyword(ref value) | >- Token::Hash(ref value) | >- Token::IDHash(ref value) | >- Token::UnquotedUrl(ref value) | >- Token::Dimension { >+ } >+ Token::Ident(ref value) >+ | Token::AtKeyword(ref value) >+ | Token::Hash(ref value) >+ | Token::IDHash(ref value) >+ | Token::UnquotedUrl(ref value) >+ | Token::Dimension { > unit: ref value, .. > } => { > if value.ends_with("�") && input.slice_from(token_start).ends_with("\\") { > // Unescaped backslash at EOF in these contexts is interpreted as U+FFFD > // Check the value in case the final backslash was itself escaped. > // Serialize as escaped U+FFFD, which is also interpreted as U+FFFD. > // (Unescaped U+FFFD would also work, but removing the backslash is annoying.) > missing_closing_characters.push_str("�") > } > if matches!(token, Token::UnquotedUrl(_)) { > check_closed!(")"); > } > token.serialization_type() >- }, >+ } > _ => token.serialization_type(), > }; > > token_start = input.position(); > token = match input.next_including_whitespace_and_comments() { > // FIXME: remove clone() when borrows are non-lexical > Ok(token) => token.clone(), > Err(..) => return Ok((first_token_type, last_token_type)), >@@ -536,63 +537,64 @@ impl<'a> CustomPropertiesBuilder<'a> { > }); > } > > let map = self.custom_properties.as_mut().unwrap(); > match specified_value { > DeclaredValue::Value(ref specified_value) => { > self.may_have_cycles |= !specified_value.references.is_empty(); > map.insert(name.clone(), (*specified_value).clone()); >- }, >+ } > DeclaredValue::WithVariables(_) => unreachable!(), > DeclaredValue::CSSWideKeyword(keyword) => match keyword { > CSSWideKeyword::Initial => { > map.remove(name); >- }, >+ } > // handled in value_may_affect_style > CSSWideKeyword::Unset | CSSWideKeyword::Inherit => unreachable!(), > }, > } > } > > fn value_may_affect_style( > &self, > name: &Name, > value: &DeclaredValue<Arc<SpecifiedValue>>, > ) -> bool { > match *value { >- DeclaredValue::CSSWideKeyword(CSSWideKeyword::Unset) | >- DeclaredValue::CSSWideKeyword(CSSWideKeyword::Inherit) => { >+ DeclaredValue::CSSWideKeyword(CSSWideKeyword::Unset) >+ | DeclaredValue::CSSWideKeyword(CSSWideKeyword::Inherit) => { > // Custom properties are inherited by default. So > // explicit 'inherit' or 'unset' means we can just use > // any existing value in the inherited CustomPropertiesMap. > return false; >- }, >- _ => {}, >+ } >+ _ => {} > } > >- let existing_value = self.custom_properties >+ let existing_value = self >+ .custom_properties > .as_ref() > .and_then(|m| m.get(name)) > .or_else(|| self.inherited.and_then(|m| m.get(name))); > > match (existing_value, value) { > (None, &DeclaredValue::CSSWideKeyword(CSSWideKeyword::Initial)) => { > // The initial value of a custom property is the same as it > // not existing in the map. > return false; >- }, >+ } > (Some(existing_value), &DeclaredValue::Value(specified_value)) => { > // Don't bother overwriting an existing inherited value with > // the same specified value. > if existing_value == specified_value { > return false; > } >- }, >- _ => {}, >+ } >+ _ => {} > } > > true > } > > /// Returns the final map of applicable custom properties. > /// > /// If there was any specified property, we've created a new map and now we need >@@ -690,21 +692,21 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap) { > if value.references.is_empty() || context.invalid.contains(&name) { > return None; > } > // Whether this variable has been visited in this traversal. > let key; > match context.index_map.entry(name) { > Entry::Occupied(entry) => { > return Some(*entry.get()); >- }, >+ } > Entry::Vacant(entry) => { > key = entry.key().clone(); > entry.insert(context.count); >- }, >+ } > } > // Hold a strong reference to the value so that we don't > // need to keep reference to context.map. > (key, value.clone()) > } else { > // The variable doesn't exist at all. > return None; > }; >@@ -723,17 +725,17 @@ fn substitute_all(custom_properties_map: &mut CustomPropertiesMap) { > let mut lowlink = index; > for next in value.references.iter() { > let next_index = match traverse(next.clone(), context) { > Some(index) => index, > // There is nothing to do if the next variable has been > // fully resolved at this point. > None => { > continue; >- }, >+ } > }; > let next_info = &context.var_info[next_index]; > if next_index > index { > // The next variable has a larger index than us, so it > // must be inserted in the recursive call above. We want > // to get its lowlink. > lowlink = cmp::min(lowlink, next_info.lowlink); > } else if next_index == index { >@@ -914,28 +916,28 @@ where > partial_computed_value, > substitute_one, > )?; > partial_computed_value.push_from(position, input, last_token_type); > } > Ok(()) > })?; > set_position_at_next_iteration = true >- }, >+ } > >- Token::Function(_) | >- Token::ParenthesisBlock | >- Token::CurlyBracketBlock | >- Token::SquareBracketBlock => { >+ Token::Function(_) >+ | Token::ParenthesisBlock >+ | Token::CurlyBracketBlock >+ | Token::SquareBracketBlock => { > input.parse_nested_block(|input| { > substitute_block(input, position, partial_computed_value, substitute_one) > })?; > // Itâs the same type for CloseCurlyBracket and CloseSquareBracket. > last_token_type = Token::CloseParenthesis.serialization_type(); >- }, >+ } > > _ => last_token_type = token.serialization_type(), > } > } > // FIXME: deal with things being implicitly closed at the end of the input. E.g. > // ```html > // <div style="--color: rgb(0,0,0"> > // <p style="background: var(--color) var(--image) top left; --image: url('a.png"></p> >diff --git a/servo/components/style/data.rs b/servo/components/style/data.rs >index 71a0ac233207..7bb22d7ad335 100644 >--- a/servo/components/style/data.rs >+++ b/servo/components/style/data.rs >@@ -267,22 +267,18 @@ impl ElementData { > element.handled_snapshot(), > element.implemented_pseudo_element() > ); > > if !element.has_snapshot() || element.handled_snapshot() { > return InvalidationResult::empty(); > } > >- let mut processor = StateAndAttrInvalidationProcessor::new( >- shared_context, >- element, >- self, >- nth_index_cache, >- ); >+ let mut processor = >+ StateAndAttrInvalidationProcessor::new(shared_context, element, self, nth_index_cache); > > let invalidator = TreeStyleInvalidator::new(element, stack_limit_checker, &mut processor); > > let result = invalidator.invalidate(); > > unsafe { element.set_handled_snapshot() } > debug_assert!(element.handled_snapshot()); > >@@ -300,17 +296,18 @@ impl ElementData { > ResolvedElementStyles { > primary: self.share_primary_style(), > pseudos: self.styles.pseudos.clone(), > } > } > > /// Returns this element's primary style as a resolved style to use for sharing. > pub fn share_primary_style(&self) -> PrimaryStyle { >- let reused_via_rule_node = self.flags >+ let reused_via_rule_node = self >+ .flags > .contains(ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE); > > PrimaryStyle { > style: ResolvedStyle(self.styles.primary().clone()), > reused_via_rule_node, > } > } > >@@ -385,17 +382,18 @@ impl ElementData { > /// If it costs too much, get_properties_overriding_animations() should return a set > /// containing only opacity and transform properties. > pub fn important_rules_are_different( > &self, > rules: &StrongRuleNode, > guards: &StylesheetGuards, > ) -> bool { > debug_assert!(self.has_styles()); >- let (important_rules, _custom) = self.styles >+ let (important_rules, _custom) = self >+ .styles > .primary() > .rules() > .get_properties_overriding_animations(&guards); > let (other_important_rules, _custom) = rules.get_properties_overriding_animations(&guards); > important_rules != other_important_rules > } > > /// Drops any restyle state from the element. >@@ -468,18 +466,18 @@ impl ElementData { > /// ellided styling. > /// > /// Second, we want to only consider elements whose ComputedValues match due to a hit > /// in the style sharing cache, rather than due to the rule-node-based reuse that > /// happens later in the styling pipeline. The former gives us the stronger guarantees > /// we need for style sharing, the latter does not. > pub fn safe_for_cousin_sharing(&self) -> bool { > !self.flags.intersects( >- ElementDataFlags::TRAVERSED_WITHOUT_STYLING | >- ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE, >+ ElementDataFlags::TRAVERSED_WITHOUT_STYLING >+ | ElementDataFlags::PRIMARY_STYLE_REUSED_VIA_RULE_NODE, > ) > } > > /// Measures memory usage. > #[cfg(feature = "gecko")] > pub fn size_of_excluding_cvs(&self, ops: &mut MallocSizeOfOps) -> usize { > let n = self.styles.size_of_excluding_cvs(ops); > >diff --git a/servo/components/style/dom.rs b/servo/components/style/dom.rs >index 42f6e9ba0c05..72e03583966a 100644 >--- a/servo/components/style/dom.rs >+++ b/servo/components/style/dom.rs >@@ -2,52 +2,55 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Types and traits used to access the DOM from style calculation. > > #![allow(unsafe_code)] > #![deny(missing_docs)] > >-use {Atom, LocalName, Namespace, WeakAtom}; > use applicable_declarations::ApplicableDeclarationBlock; > use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; > #[cfg(feature = "gecko")] > use context::PostAnimationTasks; > #[cfg(feature = "gecko")] > use context::UpdateAnimationsTasks; > use data::ElementData; > use element_state::ElementState; > use font_metrics::FontMetricsProvider; > use media_queries::Device; > use properties::{AnimationRules, ComputedValues, PropertyDeclarationBlock}; > use selector_parser::{AttrValue, PseudoClassStringArg, PseudoElement, SelectorImpl}; >-use selectors::Element as SelectorsElement; > use selectors::matching::{ElementSelectorFlags, QuirksMode, VisitedHandlingMode}; > use selectors::sink::Push; >+use selectors::Element as SelectorsElement; > use servo_arc::{Arc, ArcBorrow}; > use shared_lock::Locked; > use std::fmt; > use std::fmt::Debug; > use std::hash::Hash; > use std::ops::Deref; > use stylist::CascadeData; > use traversal_flags::TraversalFlags; >+use {Atom, LocalName, Namespace, WeakAtom}; > > /// An opaque handle to a node, which, unlike UnsafeNode, cannot be transformed > /// back into a non-opaque representation. The only safe operation that can be > /// performed on this node is to compare it to another opaque handle or to another > /// OpaqueNode. > /// > /// Layout and Graphics use this to safely represent nodes for comparison purposes. > /// Because the script task's GC does not trace layout, node data cannot be safely stored in layout > /// data structures. Also, layout code tends to be faster when the DOM is not being accessed, for > /// locality reasons. Using `OpaqueNode` enforces this invariant. > #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] >-#[cfg_attr(feature = "servo", derive(MallocSizeOf, Deserialize, Serialize))] >+#[cfg_attr( >+ feature = "servo", >+ derive(MallocSizeOf, Deserialize, Serialize) >+)] > pub struct OpaqueNode(pub usize); > > impl OpaqueNode { > /// Returns the address of this node, for debugging purposes. > #[inline] > pub fn id(&self) -> usize { > self.0 > } >@@ -454,17 +457,19 @@ pub trait TElement: > > /// Return whether this element is an element in the MathML namespace. > fn is_mathml_element(&self) -> bool; > > /// Return whether this element is an element in the SVG namespace. > fn is_svg_element(&self) -> bool; > > /// Return whether this element is an element in the XUL namespace. >- fn is_xul_element(&self) -> bool { false } >+ fn is_xul_element(&self) -> bool { >+ false >+ } > > /// Return the list of slotted nodes of this node. > fn slotted_nodes(&self) -> &[Self::ConcreteNode] { > &[] > } > > /// Get this element's style attribute. > fn style_attribute(&self) -> Option<ArcBorrow<Locked<PropertyDeclarationBlock>>>; >diff --git a/servo/components/style/dom_apis.rs b/servo/components/style/dom_apis.rs >index 393fb6e119e4..24a32ac3ba75 100644 >--- a/servo/components/style/dom_apis.rs >+++ b/servo/components/style/dom_apis.rs >@@ -1,26 +1,26 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic implementations of some DOM APIs so they can be shared between Servo > //! and Gecko. > >-use Atom; > use context::QuirksMode; > use dom::{TDocument, TElement, TNode, TShadowRoot}; > use invalidation::element::invalidator::{DescendantInvalidationLists, Invalidation}; > use invalidation::element::invalidator::{InvalidationProcessor, InvalidationVector}; >-use selectors::{Element, NthIndexCache, SelectorList}; > use selectors::attr::CaseSensitivity; > use selectors::matching::{self, MatchingContext, MatchingMode}; > use selectors::parser::{Combinator, Component, LocalName}; >+use selectors::{Element, NthIndexCache, SelectorList}; > use smallvec::SmallVec; > use std::borrow::Borrow; >+use Atom; > > /// <https://dom.spec.whatwg.org/#dom-element-matches> > pub fn element_matches<E>( > element: &E, > selector_list: &SelectorList<E::Impl>, > quirks_mode: QuirksMode, > ) -> bool > where >@@ -307,17 +307,17 @@ fn collect_elements_with_id<E, Q, F>( > Err(()) => { > let case_sensitivity = quirks_mode.classes_and_ids_case_sensitivity(); > > collect_all_elements::<E, Q, _>(root, results, |e| { > e.has_id(id, case_sensitivity) && filter(e) > }); > > return; >- }, >+ } > }; > > for element in elements { > // If the element is not an actual descendant of the root, even though > // it's connected, we don't really care about it. > if !connected_element_is_descendant_of(*element, root) { > continue; > } >@@ -342,26 +342,26 @@ fn query_selector_single_query<E, Q>( > ) -> Result<(), ()> > where > E: TElement, > Q: SelectorQuery<E>, > { > match *component { > Component::ExplicitUniversalType => { > collect_all_elements::<E, Q, _>(root, results, |_| true) >- }, >+ } > Component::ID(ref id) => { > collect_elements_with_id::<E, Q, _>(root, id, results, quirks_mode, |_| true); >- }, >+ } > Component::Class(ref class) => { > let case_sensitivity = quirks_mode.classes_and_ids_case_sensitivity(); > collect_all_elements::<E, Q, _>(root, results, |element| { > element.has_class(class, case_sensitivity) > }) >- }, >+ } > Component::LocalName(LocalName { > ref name, > ref lower_name, > }) => collect_all_elements::<E, Q, _>(root, results, |element| { > if element.is_html_element_in_html_document() { > element.local_name() == lower_name.borrow() > } else { > element.local_name() == name.borrow() >@@ -421,18 +421,17 @@ where > // root that match the selector list with that id. > collect_elements_with_id::<E, Q, _>(root, id, results, quirks_mode, |e| { > matching::matches_selector_list(selector_list, &e, matching_context) > }); > > return Ok(()); > } > >- let elements = >- fast_connected_elements_with_id(root, id, quirks_mode)?; >+ let elements = fast_connected_elements_with_id(root, id, quirks_mode)?; > if elements.is_empty() { > return Ok(()); > } > > // Results need to be in document order. Let's not bother > // reordering or deduplicating nodes, which we would need to > // do if one element with the given id were a descendant of > // another element with that given id. >@@ -464,18 +463,18 @@ where > ); > > if Q::should_stop_after_first_match() && !Q::is_empty(&results) { > break; > } > } > > return Ok(()); >- }, >- _ => {}, >+ } >+ _ => {} > } > } > > loop { > let next_combinator = match iter.next_sequence() { > None => return Err(()), > Some(c) => c, > }; >@@ -562,18 +561,18 @@ pub fn query_selector<E, Q>( > // > // The invalidation mechanism is only useful in presence of combinators. > // > // We could do that check properly here, though checking the length of the > // selectors is a good heuristic. > // > // A selector with a combinator needs to have a length of at least 3: A > // simple selector, a combinator, and another simple selector. >- let invalidation_may_be_useful = may_use_invalidation == MayUseInvalidation::Yes && >- selector_list.0.iter().any(|s| s.len() > 2); >+ let invalidation_may_be_useful = may_use_invalidation == MayUseInvalidation::Yes >+ && selector_list.0.iter().any(|s| s.len() > 2); > > if root_element.is_some() || !invalidation_may_be_useful { > query_selector_slow::<E, Q>(root, selector_list, results, &mut matching_context); > } else { > let mut processor = QuerySelectorProcessor::<E, Q> { > results, > matching_context, > selector_list, >diff --git a/servo/components/style/error_reporting.rs b/servo/components/style/error_reporting.rs >index b5d5ba17ef88..e85297eebad9 100644 >--- a/servo/components/style/error_reporting.rs >+++ b/servo/components/style/error_reporting.rs >@@ -65,17 +65,17 @@ impl<'a> fmt::Display for ContextualParseError<'a> { > int_value: Some(i), .. > } => write!(f, "number {}", i), > Token::Number { value, .. } => write!(f, "number {}", value), > Token::Percentage { > int_value: Some(i), .. > } => write!(f, "percentage {}", i), > Token::Percentage { unit_value, .. } => { > write!(f, "percentage {}", unit_value * 100.) >- }, >+ } > Token::Dimension { > value, ref unit, .. > } => write!(f, "dimension {}{}", value, unit), > Token::WhiteSpace(_) => write!(f, "whitespace"), > Token::Comment(_) => write!(f, "comment"), > Token::Colon => write!(f, "colon (:)"), > Token::Semicolon => write!(f, "semicolon (;)"), > Token::Comma => write!(f, "comma (,)"), >@@ -98,90 +98,90 @@ impl<'a> fmt::Display for ContextualParseError<'a> { > } > } > > fn parse_error_to_str(err: &ParseError, f: &mut fmt::Formatter) -> fmt::Result { > match err.kind { > ParseErrorKind::Basic(BasicParseErrorKind::UnexpectedToken(ref t)) => { > write!(f, "found unexpected ")?; > token_to_str(t, f) >- }, >+ } > ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput) => { > write!(f, "unexpected end of input") >- }, >+ } > ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(ref i)) => { > write!(f, "@ rule invalid: {}", i) >- }, >+ } > ParseErrorKind::Basic(BasicParseErrorKind::AtRuleBodyInvalid) => { > write!(f, "@ rule invalid") >- }, >+ } > ParseErrorKind::Basic(BasicParseErrorKind::QualifiedRuleInvalid) => { > write!(f, "qualified rule invalid") >- }, >+ } > ParseErrorKind::Custom(ref err) => write!(f, "{:?}", err), > } > } > > match *self { > ContextualParseError::UnsupportedPropertyDeclaration(decl, ref err) => { > write!(f, "Unsupported property declaration: '{}', ", decl)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedFontFaceDescriptor(decl, ref err) => { > write!( > f, > "Unsupported @font-face descriptor declaration: '{}', ", > decl > )?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedFontFeatureValuesDescriptor(decl, ref err) => { > write!( > f, > "Unsupported @font-feature-values descriptor declaration: '{}', ", > decl > )?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::InvalidKeyframeRule(rule, ref err) => { > write!(f, "Invalid keyframe rule: '{}', ", rule)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::InvalidFontFeatureValuesRule(rule, ref err) => { > write!(f, "Invalid font feature value rule: '{}', ", rule)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedKeyframePropertyDeclaration(decl, ref err) => { > write!(f, "Unsupported keyframe property declaration: '{}', ", decl)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::InvalidRule(rule, ref err) => { > write!(f, "Invalid rule: '{}', ", rule)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedRule(rule, ref err) => { > write!(f, "Unsupported rule: '{}', ", rule)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedViewportDescriptorDeclaration(decl, ref err) => { > write!( > f, > "Unsupported @viewport descriptor declaration: '{}', ", > decl > )?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedCounterStyleDescriptorDeclaration(decl, ref err) => { > write!( > f, > "Unsupported @counter-style descriptor declaration: '{}', ", > decl > )?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::InvalidCounterStyleWithoutSymbols(ref system) => write!( > f, > "Invalid @counter-style rule: 'system: {}' without 'symbols'", > system > ), > ContextualParseError::InvalidCounterStyleNotEnoughSymbols(ref system) => write!( > f, > "Invalid @counter-style rule: 'system: {}' less than two 'symbols'", >@@ -197,17 +197,17 @@ impl<'a> fmt::Display for ContextualParseError<'a> { > ), > ContextualParseError::InvalidCounterStyleExtendsWithAdditiveSymbols => write!( > f, > "Invalid @counter-style rule: 'system: extends â¦' with 'additive-symbols'" > ), > ContextualParseError::InvalidMediaRule(media_rule, ref err) => { > write!(f, "Invalid media rule: {}, ", media_rule)?; > parse_error_to_str(err, f) >- }, >+ } > ContextualParseError::UnsupportedValue(_value, ref err) => parse_error_to_str(err, f), > } > } > } > > /// A generic trait for an error reporter. > pub trait ParseErrorReporter { > /// Called when the style engine detects an error. >diff --git a/servo/components/style/font_face.rs b/servo/components/style/font_face.rs >index d7501c1cca7f..c74f8436bd2e 100644 >--- a/servo/components/style/font_face.rs >+++ b/servo/components/style/font_face.rs >@@ -1,39 +1,39 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! The [`@font-face`][ff] at-rule. > //! > //! [ff]: https://drafts.csswg.org/css-fonts/#at-font-face-rule > >+#[cfg(feature = "gecko")] >+use cssparser::UnicodeRange; > use cssparser::{AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; > use cssparser::{CowRcStr, SourceLocation}; >-#[cfg(feature = "gecko")] >-use cssparser::UnicodeRange; > use error_reporting::ContextualParseError; > use parser::{Parse, ParserContext}; > #[cfg(feature = "gecko")] > use properties::longhands::font_language_override; > use selectors::parser::SelectorParseErrorKind; > use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; >+use style_traits::values::SequenceWriter; > use style_traits::{Comma, CssWriter, OneOrMoreSeparated, ParseError}; > use style_traits::{StyleParseErrorKind, ToCss}; >-use style_traits::values::SequenceWriter; > use values::computed::font::FamilyName; > use values::generics::font::FontStyle as GenericFontStyle; >-use values::specified::Angle; >+use values::specified::font::SpecifiedFontStyle; > use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch}; > #[cfg(feature = "gecko")] > use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; >-use values::specified::font::SpecifiedFontStyle; > use values::specified::url::SpecifiedUrl; >+use values::specified::Angle; > > /// A source for a font-face rule. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > #[derive(Clone, Debug, Eq, PartialEq, ToCss)] > pub enum Source { > /// A `url()` source. > Url(UrlSource), > /// A `local()` source. >@@ -99,36 +99,38 @@ pub enum FontDisplay { > pub struct FontWeight(pub AbsoluteFontWeight, pub Option<AbsoluteFontWeight>); > > impl Parse for FontWeight { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let first = AbsoluteFontWeight::parse(context, input)?; >- let second = >- input.try(|input| AbsoluteFontWeight::parse(context, input)).ok(); >+ let second = input >+ .try(|input| AbsoluteFontWeight::parse(context, input)) >+ .ok(); > Ok(FontWeight(first, second)) > } > } > > /// The font-stretch descriptor: > /// > /// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-stretch > #[derive(Clone, Debug, PartialEq, ToCss)] > pub struct FontStretch(pub SpecifiedFontStretch, pub Option<SpecifiedFontStretch>); > > impl Parse for FontStretch { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let first = SpecifiedFontStretch::parse(context, input)?; >- let second = >- input.try(|input| SpecifiedFontStretch::parse(context, input)).ok(); >+ let second = input >+ .try(|input| SpecifiedFontStretch::parse(context, input)) >+ .ok(); > Ok(FontStretch(first, second)) > } > } > > /// The font-style descriptor: > /// > /// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-style > #[derive(Clone, Debug, PartialEq)] >@@ -144,19 +146,19 @@ impl Parse for FontStyle { > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let style = SpecifiedFontStyle::parse(context, input)?; > Ok(match style { > GenericFontStyle::Normal => FontStyle::Normal, > GenericFontStyle::Italic => FontStyle::Italic, > GenericFontStyle::Oblique(angle) => { >- let second_angle = input.try(|input| { >- SpecifiedFontStyle::parse_angle(context, input) >- }).unwrap_or_else(|_| angle.clone()); >+ let second_angle = input >+ .try(|input| SpecifiedFontStyle::parse_angle(context, input)) >+ .unwrap_or_else(|_| angle.clone()); > > FontStyle::Oblique(angle, second_angle) > } > }) > } > } > > impl ToCss for FontStyle { >@@ -230,25 +232,23 @@ impl<'a> FontFace<'a> { > .iter() > .rev() > .filter(|source| { > if let Source::Url(ref url_source) = **source { > let hints = &url_source.format_hints; > // We support only opentype fonts and truetype is an alias for > // that format. Sources without format hints need to be > // downloaded in case we support them. >- hints.is_empty() || >- hints.iter().any(|hint| { >- hint == "truetype" || hint == "opentype" || hint == "woff" >- }) >+ hints.is_empty() || hints >+ .iter() >+ .any(|hint| hint == "truetype" || hint == "opentype" || hint == "woff") > } else { > true > } >- }) >- .cloned() >+ }).cloned() > .collect(), > ) > } > } > > #[cfg(feature = "servo")] > impl Iterator for EffectiveSources { > type Item = Source; >diff --git a/servo/components/style/font_metrics.rs b/servo/components/style/font_metrics.rs >index dfe461cb3930..e093f13ef185 100644 >--- a/servo/components/style/font_metrics.rs >+++ b/servo/components/style/font_metrics.rs >@@ -1,22 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Access to font metrics from the style system. > > #![deny(missing_docs)] > >-use Atom; > use app_units::Au; > use context::SharedStyleContext; > use logical_geometry::WritingMode; > use media_queries::Device; > use properties::style_structs::Font; >+use Atom; > > /// Represents the font metrics that style needs from a font to compute the > /// value of certain CSS units like `ex`. > #[derive(Clone, Debug, PartialEq)] > pub struct FontMetrics { > /// The x-height of the font. > pub x_height: Au, > /// The zero advance. This is usually writing mode dependent >diff --git a/servo/components/style/gecko/arc_types.rs b/servo/components/style/gecko/arc_types.rs >index 7351cbfeac4f..2e2755d0ef1b 100644 >--- a/servo/components/style/gecko/arc_types.rs >+++ b/servo/components/style/gecko/arc_types.rs >@@ -24,26 +24,26 @@ use gecko_bindings::bindings::ServoCssRules; > use gecko_bindings::structs::RawServoAnimationValue; > use gecko_bindings::structs::RawServoDeclarationBlock; > use gecko_bindings::structs::RawServoFontFaceRule; > use gecko_bindings::structs::RawServoMediaList; > use gecko_bindings::structs::RawServoStyleRule; > use gecko_bindings::structs::RawServoStyleSheetContents; > use gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong}; > use media_queries::MediaList; >-use properties::{ComputedValues, PropertyDeclarationBlock}; > use properties::animated_properties::AnimationValue; >+use properties::{ComputedValues, PropertyDeclarationBlock}; > use rule_tree::StrongRuleNode; > use servo_arc::{Arc, ArcBorrow}; > use shared_lock::Locked; > use std::{mem, ptr}; >+use stylesheets::keyframes_rule::Keyframe; > use stylesheets::{CounterStyleRule, CssRules, FontFaceRule, FontFeatureValuesRule}; > use stylesheets::{DocumentRule, ImportRule, KeyframesRule, MediaRule, NamespaceRule, PageRule}; > use stylesheets::{StyleRule, StylesheetContents, SupportsRule}; >-use stylesheets::keyframes_rule::Keyframe; > > macro_rules! impl_arc_ffi { > ($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => { > unsafe impl HasFFI for $servo_type { > type FFIType = $gecko_type; > } > unsafe impl HasArcFFI for $servo_type {} > >diff --git a/servo/components/style/gecko/conversions.rs b/servo/components/style/gecko/conversions.rs >index 3b1f31a1b08d..fb9bfa41f68b 100644 >--- a/servo/components/style/gecko/conversions.rs >+++ b/servo/components/style/gecko/conversions.rs >@@ -7,24 +7,24 @@ > //! forces us to keep the traits and implementations here > > #![allow(unsafe_code)] > > use app_units::Au; > use gecko::values::GeckoStyleCoordConvertible; > use gecko_bindings::bindings; > use gecko_bindings::structs::{self, nsCSSUnit, nsStyleCoord_CalcValue}; >-use gecko_bindings::structs::{nsresult, SheetType, nsStyleImage}; >+use gecko_bindings::structs::{nsStyleImage, nsresult, SheetType}; > use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; > use std::f32::consts::PI; > use stylesheets::{Origin, RulesMutateError}; >+use values::computed::url::ComputedImageUrl; > use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; > use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto}; > use values::computed::{Percentage, TextAlign}; >-use values::computed::url::ComputedImageUrl; > use values::generics::box_::VerticalAlign; > use values::generics::grid::{TrackListValue, TrackSize}; > use values::generics::image::{CompatMode, GradientItem, Image as GenericImage}; > use values::generics::rect::Rect; > > impl From<CalcLengthOrPercentage> for nsStyleCoord_CalcValue { > fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { > let has_percentage = other.percentage.is_some(); >@@ -144,17 +144,20 @@ impl nsStyleImage { > pub fn set(&mut self, image: Image) { > match image { > GenericImage::Gradient(boxed_gradient) => self.set_gradient(*boxed_gradient), > GenericImage::Url(ref url) => unsafe { > bindings::Gecko_SetLayerImageImageValue(self, url.0.image_value.get()); > }, > GenericImage::Rect(ref image_rect) => { > unsafe { >- bindings::Gecko_SetLayerImageImageValue(self, image_rect.url.0.image_value.get()); >+ bindings::Gecko_SetLayerImageImageValue( >+ self, >+ image_rect.url.0.image_value.get(), >+ ); > bindings::Gecko_InitializeImageCropRect(self); > > // Set CropRect > let ref mut rect = *self.mCropRect.mPtr; > image_rect > .top > .to_gecko_style_coord(&mut rect.data_at_mut(0)); > image_rect >@@ -162,29 +165,29 @@ impl nsStyleImage { > .to_gecko_style_coord(&mut rect.data_at_mut(1)); > image_rect > .bottom > .to_gecko_style_coord(&mut rect.data_at_mut(2)); > image_rect > .left > .to_gecko_style_coord(&mut rect.data_at_mut(3)); > } >- }, >+ } > GenericImage::Element(ref element) => unsafe { > bindings::Gecko_SetImageElement(self, element.as_ptr()); > }, > } > } > > fn set_gradient(&mut self, gradient: Gradient) { >- use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER; >- use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE; >- use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER; >- use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE; > use self::structs::nsStyleCoord; >+ use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER; >+ use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE; >+ use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER; >+ use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE; > use values::computed::image::LineDirection; > use values::generics::image::{Circle, Ellipse, EndingShape, GradientKind, ShapeExtent}; > use values::specified::position::{X, Y}; > > let stop_count = gradient.items.len(); > if stop_count >= ::std::u32::MAX as usize { > warn!("stylo: Prevented overflow due to too many gradient stops"); > return; >@@ -206,49 +209,49 @@ impl nsStyleImage { > match direction { > LineDirection::Angle(angle) => { > // PI radians (180deg) is ignored because it is the default value. > if angle.radians() != PI { > unsafe { > (*gecko_gradient).mAngle.set(angle); > } > } >- }, >+ } > LineDirection::Horizontal(x) => { > let x = match x { > X::Left => 0.0, > X::Right => 1.0, > }; > > unsafe { > (*gecko_gradient) > .mBgPosX > .set_value(CoordDataValue::Percent(x)); > (*gecko_gradient) > .mBgPosY > .set_value(CoordDataValue::Percent(0.5)); > } >- }, >+ } > LineDirection::Vertical(y) => { > // Although bottom is the default value, we can not ignore > // it here, because the rendering code of Gecko relies on > // this to behave correctly for legacy mode. > let y = match y { > Y::Top => 0.0, > Y::Bottom => 1.0, > }; > unsafe { > (*gecko_gradient) > .mBgPosX > .set_value(CoordDataValue::Percent(0.5)); > (*gecko_gradient) > .mBgPosY > .set_value(CoordDataValue::Percent(y)); > } >- }, >+ } > LineDirection::Corner(horiz, vert) => { > let percent_x = match horiz { > X::Left => 0.0, > X::Right => 1.0, > }; > let percent_y = match vert { > Y::Top => 0.0, > Y::Bottom => 1.0, >@@ -257,57 +260,57 @@ impl nsStyleImage { > unsafe { > (*gecko_gradient) > .mBgPosX > .set_value(CoordDataValue::Percent(percent_x)); > (*gecko_gradient) > .mBgPosY > .set_value(CoordDataValue::Percent(percent_y)); > } >- }, >+ } > #[cfg(feature = "gecko")] > LineDirection::MozPosition(position, angle) => unsafe { > if let Some(position) = position { > (*gecko_gradient).mBgPosX.set(position.horizontal); > (*gecko_gradient).mBgPosY.set(position.vertical); > } > if let Some(angle) = angle { > (*gecko_gradient).mAngle.set(angle); > } > }, > } > gecko_gradient >- }, >+ } > GradientKind::Radial(shape, position, angle) => { > let keyword_to_gecko_size = |keyword| match keyword { > ShapeExtent::ClosestSide => CLOSEST_SIDE, > ShapeExtent::FarthestSide => FARTHEST_SIDE, > ShapeExtent::ClosestCorner => CLOSEST_CORNER, > ShapeExtent::FarthestCorner => FARTHEST_CORNER, > ShapeExtent::Contain => CLOSEST_SIDE, > ShapeExtent::Cover => FARTHEST_CORNER, > }; > let (gecko_shape, gecko_size) = match shape { > EndingShape::Circle(ref circle) => { > let size = match *circle { > Circle::Extent(extent) => keyword_to_gecko_size(extent), > _ => structs::NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE, > }; > (structs::NS_STYLE_GRADIENT_SHAPE_CIRCULAR as u8, size as u8) >- }, >+ } > EndingShape::Ellipse(ref ellipse) => { > let size = match *ellipse { > Ellipse::Extent(extent) => keyword_to_gecko_size(extent), > _ => structs::NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE, > }; > ( > structs::NS_STYLE_GRADIENT_SHAPE_ELLIPTICAL as u8, > size as u8, > ) >- }, >+ } > }; > > let gecko_gradient = unsafe { > bindings::Gecko_CreateGradient( > gecko_shape, > gecko_size, > gradient.repeating, > gradient.compat_mode == CompatMode::Moz, >@@ -333,44 +336,44 @@ impl nsStyleImage { > (*gecko_gradient) > .mRadiusY > .set_value(CoordDataValue::Coord(au)); > }, > EndingShape::Ellipse(Ellipse::Radii(x, y)) => unsafe { > (*gecko_gradient).mRadiusX.set(x); > (*gecko_gradient).mRadiusY.set(y); > }, >- _ => {}, >+ _ => {} > } > unsafe { > (*gecko_gradient).mBgPosX.set(position.horizontal); > (*gecko_gradient).mBgPosY.set(position.vertical); > } > > gecko_gradient >- }, >+ } > }; > > for (index, item) in gradient.items.iter().enumerate() { > // NB: stops are guaranteed to be none in the gecko side by > // default. > > let gecko_stop = unsafe { &mut (*gecko_gradient).mStops[index] }; > let mut coord = nsStyleCoord::null(); > > match *item { > GradientItem::ColorStop(ref stop) => { > gecko_stop.mColor = stop.color.into(); > gecko_stop.mIsInterpolationHint = false; > coord.set(stop.position); >- }, >+ } > GradientItem::InterpolationHint(hint) => { > gecko_stop.mIsInterpolationHint = true; > coord.set(Some(hint)); >- }, >+ } > } > > gecko_stop.mLocation.move_from(coord); > } > > unsafe { > bindings::Gecko_SetGradientImageValue(self, gecko_gradient); > } >@@ -398,53 +401,54 @@ impl nsStyleImage { > (Some(top), Some(right), Some(bottom), Some(left)) => { > Some(GenericImage::Rect(Box::new(MozImageRect { > url, > top, > right, > bottom, > left, > }))) >- }, >+ } > _ => { > debug_assert!( > false, > "mCropRect could not convert to NumberOrPercentage" > ); > None >- }, >+ } > } > } >- }, >+ } > nsStyleImageType::eStyleImageType_Gradient => { > Some(GenericImage::Gradient(self.get_gradient())) >- }, >+ } > nsStyleImageType::eStyleImageType_Element => { > use gecko_string_cache::Atom; > let atom = bindings::Gecko_GetImageElement(self); > Some(GenericImage::Element(Atom::from_raw(atom))) >- }, >+ } > _ => panic!("Unexpected image type"), > } > } > > unsafe fn get_image_url(&self) -> ComputedImageUrl { > let image_request = bindings::Gecko_GetImageRequest(self) >- .as_ref().expect("Null image request?"); >+ .as_ref() >+ .expect("Null image request?"); > ComputedImageUrl::from_image_request(image_request) > } > > unsafe fn get_gradient(self: &nsStyleImage) -> Box<Gradient> { > use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER as CLOSEST_CORNER; > use self::structs::NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE as CLOSEST_SIDE; > use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER as FARTHEST_CORNER; > use self::structs::NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE as FARTHEST_SIDE; >- use values::computed::{Length, LengthOrPercentage}; > use values::computed::image::LineDirection; > use values::computed::position::Position; >+ use values::computed::{Length, LengthOrPercentage}; > use values::generics::image::{Circle, ColorStop, CompatMode, Ellipse}; > use values::generics::image::{EndingShape, GradientKind, ShapeExtent}; > use values::specified::position::{X, Y}; > > let gecko_gradient = bindings::Gecko_GetGradientImageValue(self) > .as_ref() > .unwrap(); > let angle = Angle::from_gecko_style_coord(&gecko_gradient.mAngle); >@@ -460,60 +464,60 @@ impl nsStyleImage { > LengthOrPercentage::Percentage(percentage) => { > if percentage.0 == 0.0 { > Some(X::Left) > } else if percentage.0 == 1.0 { > Some(X::Right) > } else { > None > } >- }, >+ } > _ => None, > }; > let vertical_as_corner = match vertical { > LengthOrPercentage::Percentage(percentage) => { > if percentage.0 == 0.0 { > Some(Y::Top) > } else if percentage.0 == 1.0 { > Some(Y::Bottom) > } else { > None > } >- }, >+ } > _ => None, > }; > > match (horizontal_as_corner, vertical_as_corner) { > (Some(hc), Some(vc)) => LineDirection::Corner(hc, vc), > _ => LineDirection::MozPosition( > Some(Position { > horizontal, > vertical, > }), > None, > ), > } >- }, >+ } > (Some(_), Some(horizontal), Some(vertical)) => LineDirection::MozPosition( > Some(Position { > horizontal, > vertical, > }), > angle, > ), > _ => { > debug_assert!( > horizontal_style.is_none() && vertical_style.is_none(), > "Unexpected linear gradient direction" > ); > LineDirection::MozPosition(None, None) >- }, >+ } > }; > GradientKind::Linear(line_direction) >- }, >+ } > _ => { > let gecko_size_to_keyword = |gecko_size| { > match gecko_size { > CLOSEST_SIDE => ShapeExtent::ClosestSide, > FARTHEST_SIDE => ShapeExtent::FarthestSide, > CLOSEST_CORNER => ShapeExtent::ClosestCorner, > FARTHEST_CORNER => ShapeExtent::FarthestCorner, > // FIXME: We should support ShapeExtent::Contain and ShapeExtent::Cover. >@@ -522,30 +526,30 @@ impl nsStyleImage { > _ => panic!("Found unexpected gecko_size"), > } > }; > > let shape = match gecko_gradient.mShape as u32 { > structs::NS_STYLE_GRADIENT_SHAPE_CIRCULAR => { > let circle = match gecko_gradient.mSize as u32 { > structs::NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE => { >- let radius = Length::from_gecko_style_coord( >- &gecko_gradient.mRadiusX, >- ).expect("mRadiusX could not convert to Length"); >+ let radius = >+ Length::from_gecko_style_coord(&gecko_gradient.mRadiusX) >+ .expect("mRadiusX could not convert to Length"); > debug_assert_eq!( > radius, > Length::from_gecko_style_coord(&gecko_gradient.mRadiusY) > .unwrap() > ); > Circle::Radius(radius) >- }, >+ } > size => Circle::Extent(gecko_size_to_keyword(size)), > }; > EndingShape::Circle(circle) >- }, >+ } > structs::NS_STYLE_GRADIENT_SHAPE_ELLIPTICAL => { > let length_percentage_keyword = match gecko_gradient.mSize as u32 { > structs::NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE => match ( > LengthOrPercentage::from_gecko_style_coord( > &gecko_gradient.mRadiusX, > ), > LengthOrPercentage::from_gecko_style_coord( > &gecko_gradient.mRadiusY, >@@ -554,22 +558,22 @@ impl nsStyleImage { > (Some(x), Some(y)) => Ellipse::Radii(x, y), > _ => { > debug_assert!(false, > "mRadiusX, mRadiusY could not convert to LengthOrPercentage"); > Ellipse::Radii( > LengthOrPercentage::zero(), > LengthOrPercentage::zero(), > ) >- }, >+ } > }, > size => Ellipse::Extent(gecko_size_to_keyword(size)), > }; > EndingShape::Ellipse(length_percentage_keyword) >- }, >+ } > _ => panic!("Found unexpected mShape"), > }; > > let position = match (horizontal_style, vertical_style) { > (Some(horizontal), Some(vertical)) => Position { > horizontal, > vertical, > }, >@@ -577,21 +581,21 @@ impl nsStyleImage { > debug_assert!( > false, > "mRadiusX, mRadiusY could not convert to LengthOrPercentage" > ); > Position { > horizontal: LengthOrPercentage::zero(), > vertical: LengthOrPercentage::zero(), > } >- }, >+ } > }; > > GradientKind::Radial(shape, position, angle) >- }, >+ } > }; > > let items = gecko_gradient > .mStops > .iter() > .map(|ref stop| { > if stop.mIsInterpolationHint { > GradientItem::InterpolationHint( >@@ -599,18 +603,17 @@ impl nsStyleImage { > .expect("mLocation could not convert to LengthOrPercentage"), > ) > } else { > GradientItem::ColorStop(ColorStop { > color: stop.mColor.into(), > position: LengthOrPercentage::from_gecko_style_coord(&stop.mLocation), > }) > } >- }) >- .collect(); >+ }).collect(); > > let compat_mode = if gecko_gradient.mMozLegacySyntax { > CompatMode::Moz > } else if gecko_gradient.mLegacySyntax { > CompatMode::WebKit > } else { > CompatMode::Modern > }; >@@ -624,19 +627,19 @@ impl nsStyleImage { > } > } > > pub mod basic_shape { > //! Conversions from and to CSS shape representations. > > use gecko::values::GeckoStyleCoordConvertible; > use gecko_bindings::structs; >+ use gecko_bindings::structs::{nsStyleCoord, nsStyleCorners}; > use gecko_bindings::structs::{StyleBasicShape, StyleBasicShapeType, StyleFillRule}; > use gecko_bindings::structs::{StyleGeometryBox, StyleShapeSource, StyleShapeSourceType}; >- use gecko_bindings::structs::{nsStyleCoord, nsStyleCorners}; > use gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue}; > use gecko_bindings::sugar::refptr::RefPtr; > use std::borrow::Borrow; > use values::computed::basic_shape::{BasicShape, ClippingShape, FloatAreaShape, ShapeRadius}; > use values::computed::border::{BorderCornerRadius, BorderRadius}; > use values::computed::length::LengthOrPercentage; > use values::computed::position; > use values::computed::url::ComputedUrl; >@@ -662,47 +665,47 @@ pub mod basic_shape { > let other_shape = unsafe { &*self.__bindgen_anon_1.mBasicShape.as_ref().mPtr }; > let shape = other_shape.into(); > let reference_box = if self.mReferenceBox == StyleGeometryBox::NoBox { > None > } else { > Some(self.mReferenceBox.into()) > }; > Some(ShapeSource::Shape(shape, reference_box)) >- }, >+ } > StyleShapeSourceType::URL | StyleShapeSourceType::Image => None, > } > } > } > > impl<'a> From<&'a StyleShapeSource> for ClippingShape { > fn from(other: &'a StyleShapeSource) -> Self { > match other.mType { > StyleShapeSourceType::URL => unsafe { > let shape_image = &*other.__bindgen_anon_1.mShapeImage.as_ref().mPtr; > let other_url = RefPtr::new(*shape_image.__bindgen_anon_1.mURLValue.as_ref()); > let url = ComputedUrl::from_url_value(other_url); > ShapeSource::ImageOrUrl(url) > }, > StyleShapeSourceType::Image => { > unreachable!("ClippingShape doesn't support Image!"); >- }, >+ } > _ => other > .into_shape_source() > .expect("Couldn't convert to StyleSource!"), > } > } > } > > impl<'a> From<&'a StyleShapeSource> for FloatAreaShape { > fn from(other: &'a StyleShapeSource) -> Self { > match other.mType { > StyleShapeSourceType::URL => { > unreachable!("FloatAreaShape doesn't support URL!"); >- }, >+ } > StyleShapeSourceType::Image => unsafe { > let shape_image = &*other.__bindgen_anon_1.mShapeImage.as_ref().mPtr; > let image = shape_image.into_image().expect("Cannot convert to Image"); > ShapeSource::ImageOrUrl(image) > }, > _ => other > .into_shape_source() > .expect("Couldn't convert to StyleSource!"), >@@ -724,17 +727,17 @@ pub mod basic_shape { > r.expect("inset() offset should be a length, percentage, or calc value"), > b.expect("inset() offset should be a length, percentage, or calc value"), > l.expect("inset() offset should be a length, percentage, or calc value"), > ); > GenericBasicShape::Inset(InsetRect { > rect: rect, > round: Some(round), > }) >- }, >+ } > StyleBasicShapeType::Circle => GenericBasicShape::Circle(Circle { > radius: (&other.mCoordinates[0]).into(), > position: (&other.mPosition).into(), > }), > StyleBasicShapeType::Ellipse => GenericBasicShape::Ellipse(Ellipse { > semiaxis_x: (&other.mCoordinates[0]).into(), > semiaxis_y: (&other.mCoordinates[1]).into(), > position: (&other.mPosition).into(), >@@ -754,17 +757,17 @@ pub mod basic_shape { > LengthOrPercentage::from_gecko_style_coord(&other.mCoordinates[y]) > .expect("polygon() coordinate should be a length, percentage, or calc value") > )) > } > GenericBasicShape::Polygon(Polygon { > fill: fill_rule, > coordinates: coords, > }) >- }, >+ } > } > } > } > > impl<'a> From<&'a nsStyleCorners> for BorderRadius { > fn from(other: &'a nsStyleCorners) -> Self { > let get_corner = |index| { > BorderCornerRadius::new( >@@ -927,19 +930,19 @@ impl TrackSize<LengthOrPercentage> { > /// Return TrackSize from given two nsStyleCoord > pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self { > use gecko_bindings::structs::root::nsStyleUnit; > use values::computed::length::LengthOrPercentage; > use values::generics::grid::{TrackBreadth, TrackSize}; > > if gecko_min.unit() == nsStyleUnit::eStyleUnit_None { > debug_assert!( >- gecko_max.unit() == nsStyleUnit::eStyleUnit_Coord || >- gecko_max.unit() == nsStyleUnit::eStyleUnit_Percent || >- gecko_max.unit() == nsStyleUnit::eStyleUnit_Calc >+ gecko_max.unit() == nsStyleUnit::eStyleUnit_Coord >+ || gecko_max.unit() == nsStyleUnit::eStyleUnit_Percent >+ || gecko_max.unit() == nsStyleUnit::eStyleUnit_Calc > ); > return TrackSize::FitContent( > LengthOrPercentage::from_gecko_style_coord(gecko_max) > .expect("gecko_max could not convert to LengthOrPercentage"), > ); > } > > let min = TrackBreadth::from_gecko_style_coord(gecko_min) >@@ -958,27 +961,27 @@ impl TrackSize<LengthOrPercentage> { > use values::generics::grid::TrackSize; > > match *self { > TrackSize::FitContent(ref lop) => { > // Gecko sets min value to None and max value to the actual value in fit-content > // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8221 > gecko_min.set_value(CoordDataValue::None); > lop.to_gecko_style_coord(gecko_max); >- }, >+ } > TrackSize::Breadth(ref breadth) => { > // Set the value to both fields if there's one breadth value > // https://dxr.mozilla.org/mozilla-central/rev/0eef1d5/layout/style/nsRuleNode.cpp#8230 > breadth.to_gecko_style_coord(gecko_min); > breadth.to_gecko_style_coord(gecko_max); >- }, >+ } > TrackSize::Minmax(ref min, ref max) => { > min.to_gecko_style_coord(gecko_min); > max.to_gecko_style_coord(gecko_max); >- }, >+ } > } > } > } > > impl TrackListValue<LengthOrPercentage, Integer> { > /// Return TrackSize from given two nsStyleCoord > pub fn from_gecko_style_coords<T: CoordData>(gecko_min: &T, gecko_max: &T) -> Self { > TrackListValue::TrackSize(TrackSize::from_gecko_style_coords(gecko_min, gecko_max)) >@@ -1031,17 +1034,17 @@ impl<L> VerticalAlign<L> { > structs::NS_STYLE_VERTICAL_ALIGN_SUPER => VerticalAlign::Super, > structs::NS_STYLE_VERTICAL_ALIGN_TOP => VerticalAlign::Top, > structs::NS_STYLE_VERTICAL_ALIGN_TEXT_TOP => VerticalAlign::TextTop, > structs::NS_STYLE_VERTICAL_ALIGN_MIDDLE => VerticalAlign::Middle, > structs::NS_STYLE_VERTICAL_ALIGN_BOTTOM => VerticalAlign::Bottom, > structs::NS_STYLE_VERTICAL_ALIGN_TEXT_BOTTOM => VerticalAlign::TextBottom, > structs::NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE => { > VerticalAlign::MozMiddleWithBaseline >- }, >+ } > _ => panic!("unexpected enumerated value for vertical-align"), > } > } > } > > impl TextAlign { > /// Obtain a specified value from a Gecko keyword value > /// >diff --git a/servo/components/style/gecko/data.rs b/servo/components/style/gecko/data.rs >index 0bd938c67e8f..19c97572137e 100644 >--- a/servo/components/style/gecko/data.rs >+++ b/servo/components/style/gecko/data.rs >@@ -3,18 +3,20 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Data needed to style a Gecko document. > > use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; > use context::QuirksMode; > use dom::TElement; > use gecko_bindings::bindings::{self, RawServoStyleSet}; >-use gecko_bindings::structs::{RawGeckoPresContextOwned, ServoStyleSetSizes, StyleSheet as DomStyleSheet}; >-use gecko_bindings::structs::{StyleSheetInfo, nsIDocument}; >+use gecko_bindings::structs::{nsIDocument, StyleSheetInfo}; >+use gecko_bindings::structs::{ >+ RawGeckoPresContextOwned, ServoStyleSetSizes, StyleSheet as DomStyleSheet, >+}; > use gecko_bindings::sugar::ownership::{HasArcFFI, HasBoxFFI, HasFFI, HasSimpleFFI}; > use invalidation::media_queries::{MediaListKey, ToMediaListKey}; > use malloc_size_of::MallocSizeOfOps; > use media_queries::{Device, MediaList}; > use properties::ComputedValues; > use selector_parser::SnapshotMap; > use servo_arc::Arc; > use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; >@@ -24,17 +26,18 @@ use stylist::Stylist; > > /// Little wrapper to a Gecko style sheet. > #[derive(Eq, PartialEq)] > pub struct GeckoStyleSheet(*const DomStyleSheet); > > impl fmt::Debug for GeckoStyleSheet { > fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { > let contents = self.contents(); >- formatter.debug_struct("GeckoStyleSheet") >+ formatter >+ .debug_struct("GeckoStyleSheet") > .field("origin", &contents.origin) > .field("url_data", &*contents.url_data.read()) > .finish() > } > } > > impl ToMediaListKey for ::gecko::data::GeckoStyleSheet { > fn to_media_list_key(&self) -> MediaListKey { >@@ -61,19 +64,17 @@ impl GeckoStyleSheet { > } > > /// Get the raw `StyleSheet` that we're wrapping. > pub fn raw(&self) -> &DomStyleSheet { > unsafe { &*self.0 } > } > > fn inner(&self) -> &StyleSheetInfo { >- unsafe { >- &*(self.raw().mInner as *const StyleSheetInfo) >- } >+ unsafe { &*(self.raw().mInner as *const StyleSheetInfo) } > } > > /// Gets the StylesheetContents for this stylesheet. > pub fn contents(&self) -> &StylesheetContents { > debug_assert!(!self.inner().mContents.mRawPtr.is_null()); > unsafe { > let contents = > (&**StylesheetContents::as_arc(&&*self.inner().mContents.mRawPtr)) as *const _; >@@ -188,17 +189,18 @@ impl PerDocumentStyleDataImpl { > /// Get the default computed values for this document. > pub fn default_computed_values(&self) -> &Arc<ComputedValues> { > self.stylist.device().default_computed_values_arc() > } > > /// Returns whether visited styles are enabled. > #[inline] > pub fn visited_styles_enabled(&self) -> bool { >- let doc = self.stylist >+ let doc = self >+ .stylist > .device() > .pres_context() > .mDocument > .raw::<nsIDocument>(); > unsafe { bindings::Gecko_VisitedStylesEnabled(doc) } > } > > /// Measure heap usage. >diff --git a/servo/components/style/gecko/global_style_data.rs b/servo/components/style/gecko/global_style_data.rs >index 6671de9867d2..8007acb6ce2a 100644 >--- a/servo/components/style/gecko/global_style_data.rs >+++ b/servo/components/style/gecko/global_style_data.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Global style data > > use context::StyleSystemOptions; >-use gecko_bindings::bindings::{Gecko_RegisterProfilerThread, Gecko_UnregisterProfilerThread}; > use gecko_bindings::bindings::Gecko_SetJemallocThreadLocalArena; >+use gecko_bindings::bindings::{Gecko_RegisterProfilerThread, Gecko_UnregisterProfilerThread}; > use num_cpus; > use parallel::STYLE_THREAD_STACK_SIZE_KB; > use rayon; > use shared_lock::SharedRwLock; > use std::cmp; > use std::env; > use std::ffi::CString; > use thread_state; >diff --git a/servo/components/style/gecko/media_features.rs b/servo/components/style/gecko/media_features.rs >index 3595133f55c1..2958bb0a488d 100644 >--- a/servo/components/style/gecko/media_features.rs >+++ b/servo/components/style/gecko/media_features.rs >@@ -1,57 +1,53 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Gecko's media feature list and evaluator. > >-use Atom; > use app_units::Au; > use euclid::Size2D; > use gecko_bindings::bindings; > use values::computed::CSSPixelLength; > use values::computed::Resolution; >+use Atom; > >-use media_queries::Device; >-use media_queries::media_feature::{MediaFeatureDescription, Evaluator}; > use media_queries::media_feature::{AllowsRanges, ParsingRequirements}; >+use media_queries::media_feature::{Evaluator, MediaFeatureDescription}; > use media_queries::media_feature_expression::{AspectRatio, RangeOrOperator}; >+use media_queries::Device; > > macro_rules! feature { > ($name:expr, $allows_ranges:expr, $evaluator:expr, $reqs:expr,) => { > MediaFeatureDescription { > name: $name, > allows_ranges: $allows_ranges, > evaluator: $evaluator, > requirements: $reqs, > } >- } >+ }; > } > > fn viewport_size(device: &Device) -> Size2D<Au> { > let pc = device.pres_context(); > if pc.mIsRootPaginatedDocument() != 0 { > // We want the page size, including unprintable areas and margins. > // FIXME(emilio, bug 1414600): Not quite! > let area = &pc.mPageSize; >- return Size2D::new(Au(area.width), Au(area.height)) >+ return Size2D::new(Au(area.width), Au(area.height)); > } > device.au_viewport_size() > } > > fn device_size(device: &Device) -> Size2D<Au> { > let mut width = 0; > let mut height = 0; > unsafe { >- bindings::Gecko_MediaFeatures_GetDeviceSize( >- device.document(), >- &mut width, >- &mut height, >- ); >+ bindings::Gecko_MediaFeatures_GetDeviceSize(device.document(), &mut width, &mut height); > } > Size2D::new(Au(width), Au(height)) > } > > /// https://drafts.csswg.org/mediaqueries-4/#width > fn eval_width( > device: &Device, > value: Option<CSSPixelLength>, >@@ -159,21 +155,17 @@ fn eval_device_pixel_ratio( > > #[derive(Debug, Copy, Clone, FromPrimitive, ToCss, Parse)] > #[repr(u8)] > enum Orientation { > Landscape, > Portrait, > } > >-fn eval_orientation_for<F>( >- device: &Device, >- value: Option<Orientation>, >- get_size: F, >-) -> bool >+fn eval_orientation_for<F>(device: &Device, value: Option<Orientation>, get_size: F) -> bool > where > F: FnOnce(&Device) -> Size2D<Au>, > { > let query_orientation = match value { > Some(v) => v, > None => return true, > }; > >@@ -183,74 +175,60 @@ where > let is_landscape = size.width > size.height; > match query_orientation { > Orientation::Landscape => is_landscape, > Orientation::Portrait => !is_landscape, > } > } > > /// https://drafts.csswg.org/mediaqueries-4/#orientation >-fn eval_orientation( >- device: &Device, >- value: Option<Orientation>, >-) -> bool { >+fn eval_orientation(device: &Device, value: Option<Orientation>) -> bool { > eval_orientation_for(device, value, viewport_size) > } > > /// FIXME: There's no spec for `-moz-device-orientation`. >-fn eval_device_orientation( >- device: &Device, >- value: Option<Orientation>, >-) -> bool { >+fn eval_device_orientation(device: &Device, value: Option<Orientation>) -> bool { > eval_orientation_for(device, value, device_size) > } > > /// Values for the display-mode media feature. > #[derive(Debug, Copy, Clone, FromPrimitive, ToCss, Parse)] > #[repr(u8)] > #[allow(missing_docs)] > pub enum DisplayMode { >- Browser = 0, >- MinimalUi, >- Standalone, >- Fullscreen, >+ Browser = 0, >+ MinimalUi, >+ Standalone, >+ Fullscreen, > } > > /// https://w3c.github.io/manifest/#the-display-mode-media-feature >-fn eval_display_mode( >- device: &Device, >- query_value: Option<DisplayMode>, >-) -> bool { >+fn eval_display_mode(device: &Device, query_value: Option<DisplayMode>) -> bool { > let query_value = match query_value { > Some(v) => v, > None => return true, > }; > >- let gecko_display_mode = unsafe { >- bindings::Gecko_MediaFeatures_GetDisplayMode(device.document()) >- }; >+ let gecko_display_mode = >+ unsafe { bindings::Gecko_MediaFeatures_GetDisplayMode(device.document()) }; > > // NOTE: cbindgen guarantees the same representation. > gecko_display_mode as u8 == query_value as u8 > } > > /// https://drafts.csswg.org/mediaqueries-4/#grid > fn eval_grid(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool { > // Gecko doesn't support grid devices (e.g., ttys), so the 'grid' feature > // is always 0. > let supports_grid = false; > query_value.map_or(supports_grid, |v| v == supports_grid) > } > > /// https://compat.spec.whatwg.org/#css-media-queries-webkit-transform-3d >-fn eval_transform_3d( >- _: &Device, >- query_value: Option<bool>, >- _: Option<RangeOrOperator>, >-) -> bool { >+fn eval_transform_3d(_: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool { > let supports_transforms = true; > query_value.map_or(supports_transforms, |v| v == supports_transforms) > } > > #[derive(Debug, Copy, Clone, FromPrimitive, ToCss, Parse)] > #[repr(u8)] > enum Scan { > Progressive, >@@ -267,81 +245,65 @@ fn eval_scan(_: &Device, _: Option<Scan>) -> bool { > /// https://drafts.csswg.org/mediaqueries-4/#color > fn eval_color( > device: &Device, > query_value: Option<u32>, > range_or_operator: Option<RangeOrOperator>, > ) -> bool { > let color_bits_per_channel = > unsafe { bindings::Gecko_MediaFeatures_GetColorDepth(device.document()) }; >- RangeOrOperator::evaluate( >- range_or_operator, >- query_value, >- color_bits_per_channel, >- ) >+ RangeOrOperator::evaluate(range_or_operator, query_value, color_bits_per_channel) > } > > /// https://drafts.csswg.org/mediaqueries-4/#color-index > fn eval_color_index( > _: &Device, > query_value: Option<u32>, > range_or_operator: Option<RangeOrOperator>, > ) -> bool { > // We should return zero if the device does not use a color lookup table. > let index = 0; >- RangeOrOperator::evaluate( >- range_or_operator, >- query_value, >- index, >- ) >+ RangeOrOperator::evaluate(range_or_operator, query_value, index) > } > > /// https://drafts.csswg.org/mediaqueries-4/#monochrome > fn eval_monochrome( > _: &Device, > query_value: Option<u32>, > range_or_operator: Option<RangeOrOperator>, > ) -> bool { > // For color devices we should return 0. > // FIXME: On a monochrome device, return the actual color depth, not 0! > let depth = 0; >- RangeOrOperator::evaluate( >- range_or_operator, >- query_value, >- depth, >- ) >+ RangeOrOperator::evaluate(range_or_operator, query_value, depth) > } > > /// https://drafts.csswg.org/mediaqueries-4/#resolution > fn eval_resolution( > device: &Device, > query_value: Option<Resolution>, > range_or_operator: Option<RangeOrOperator>, > ) -> bool { >- let resolution_dppx = >- unsafe { bindings::Gecko_MediaFeatures_GetResolution(device.document()) }; >+ let resolution_dppx = unsafe { bindings::Gecko_MediaFeatures_GetResolution(device.document()) }; > RangeOrOperator::evaluate( > range_or_operator, > query_value.map(|r| r.dppx()), > resolution_dppx, > ) > } > > #[derive(Debug, Copy, Clone, FromPrimitive, ToCss, Parse)] > #[repr(u8)] > enum PrefersReducedMotion { > NoPreference, > Reduce, > } > > /// https://drafts.csswg.org/mediaqueries-5/#prefers-reduced-motion >-fn eval_prefers_reduced_motion( >- device: &Device, >- query_value: Option<PrefersReducedMotion>, >-) -> bool { >+fn eval_prefers_reduced_motion(device: &Device, query_value: Option<PrefersReducedMotion>) -> bool { > let prefers_reduced = > unsafe { bindings::Gecko_MediaFeatures_PrefersReducedMotion(device.document()) }; > let query_value = match query_value { > Some(v) => v, > None => return prefers_reduced, > }; > > match query_value { >@@ -359,19 +321,18 @@ fn eval_moz_is_glyph( > query_value.map_or(is_glyph, |v| v == is_glyph) > } > > fn eval_moz_is_resource_document( > device: &Device, > query_value: Option<bool>, > _: Option<RangeOrOperator>, > ) -> bool { >- let is_resource_doc = unsafe { >- bindings::Gecko_MediaFeatures_IsResourceDocument(device.document()) >- }; >+ let is_resource_doc = >+ unsafe { bindings::Gecko_MediaFeatures_IsResourceDocument(device.document()) }; > query_value.map_or(is_resource_doc, |v| v == is_resource_doc) > } > > fn eval_system_metric( > device: &Device, > query_value: Option<bool>, > metric: Atom, > accessible_from_content: bool, >@@ -404,47 +365,40 @@ fn eval_moz_os_version( > query_value: Option<Atom>, > _: Option<RangeOrOperator>, > ) -> bool { > let query_value = match query_value { > Some(v) => v, > None => return false, > }; > >- let os_version = unsafe { >- bindings::Gecko_MediaFeatures_GetOperatingSystemVersion(device.document()) >- }; >+ let os_version = >+ unsafe { bindings::Gecko_MediaFeatures_GetOperatingSystemVersion(device.document()) }; > > query_value.as_ptr() == os_version > } > > macro_rules! system_metric_feature { >- ($feature_name:expr) => { >- { >- fn __eval( >- device: &Device, >- query_value: Option<bool>, >- _: Option<RangeOrOperator>, >- ) -> bool { >- eval_system_metric( >- device, >- query_value, >- $feature_name, >- /* accessible_from_content = */ false, >- ) >- } >- >- feature!( >+ ($feature_name:expr) => {{ >+ fn __eval(device: &Device, query_value: Option<bool>, _: Option<RangeOrOperator>) -> bool { >+ eval_system_metric( >+ device, >+ query_value, > $feature_name, >- AllowsRanges::No, >- Evaluator::BoolInteger(__eval), >- ParsingRequirements::CHROME_AND_UA_ONLY, >+ /* accessible_from_content = */ false, > ) > } >- } >+ >+ feature!( >+ $feature_name, >+ AllowsRanges::No, >+ Evaluator::BoolInteger(__eval), >+ ParsingRequirements::CHROME_AND_UA_ONLY, >+ ) >+ }}; > } > > lazy_static! { > /// Adding new media features requires (1) adding the new feature to this > /// array, with appropriate entries (and potentially any new code needed > /// to support new types in these entries and (2) ensuring that either > /// nsPresContext::MediaFeatureValuesChanged is called when the value that > /// would be returned by the evaluator function could change. >diff --git a/servo/components/style/gecko/media_queries.rs b/servo/components/style/gecko/media_queries.rs >index c41bc4ffd73e..9b77c6a00d81 100644 >--- a/servo/components/style/gecko/media_queries.rs >+++ b/servo/components/style/gecko/media_queries.rs >@@ -1,33 +1,33 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Gecko's media-query device and expression representation. > >-use app_units::AU_PER_PX; > use app_units::Au; >+use app_units::AU_PER_PX; > use cssparser::RGBA; > use euclid::Size2D; > use euclid::TypedScale; > use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor}; > use gecko_bindings::bindings; > use gecko_bindings::structs; > use gecko_bindings::structs::{nsPresContext, RawGeckoPresContextOwned}; > use media_queries::MediaType; > use properties::ComputedValues; > use servo_arc::Arc; > use std::fmt; > use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize, Ordering}; > use string_cache::Atom; >-use style_traits::{CSSPixel, DevicePixel}; > use style_traits::viewport::ViewportConstraints; >-use values::{CustomIdent, KeyframesName}; >+use style_traits::{CSSPixel, DevicePixel}; > use values::computed::font::FontSize; >+use values::{CustomIdent, KeyframesName}; > > /// The `Device` in Gecko wraps a pres context, has a default values computed, > /// and contains all the viewport rule state. > pub struct Device { > /// NB: The pres context lifetime is tied to the styleset, who owns the > /// stylist, and thus the `Device`, so having a raw pres context pointer > /// here is fine. > pres_context: RawGeckoPresContextOwned, >@@ -121,17 +121,18 @@ impl Device { > /// Get the font size of the root element (for rem) > pub fn root_font_size(&self) -> Au { > self.used_root_font_size.store(true, Ordering::Relaxed); > Au::new(self.root_font_size.load(Ordering::Relaxed) as i32) > } > > /// Set the font size of the root element (for rem) > pub fn set_root_font_size(&self, size: Au) { >- self.root_font_size.store(size.0 as isize, Ordering::Relaxed) >+ self.root_font_size >+ .store(size.0 as isize, Ordering::Relaxed) > } > > /// Sets the body text color for the "inherit color from body" quirk. > /// > /// <https://quirks.spec.whatwg.org/#the-tables-inherit-color-from-body-quirk> > pub fn set_body_text_color(&self, color: RGBA) { > self.body_text_color > .store(convert_rgba_to_nscolor(&color) as usize, Ordering::Relaxed) >diff --git a/servo/components/style/gecko/pseudo_element.rs b/servo/components/style/gecko/pseudo_element.rs >index a08da8d40f13..7c4fe22c2a9e 100644 >--- a/servo/components/style/gecko/pseudo_element.rs >+++ b/servo/components/style/gecko/pseudo_element.rs >@@ -5,18 +5,18 @@ > //! Gecko's definition of a pseudo-element. > //! > //! Note that a few autogenerated bits of this live in > //! `pseudo_element_definition.mako.rs`. If you touch that file, you probably > //! need to update the checked-in files for Servo. > > use cssparser::ToCss; > use gecko_bindings::structs::{self, CSSPseudoElementType}; >-use properties::{ComputedValues, PropertyFlags}; > use properties::longhands::display::computed_value::T as Display; >+use properties::{ComputedValues, PropertyFlags}; > use selector_parser::{NonTSPseudoClass, PseudoElementCascadeType, SelectorImpl}; > use std::fmt; > use string_cache::Atom; > use thin_slice::ThinBoxedSlice; > use values::serialize_atom_identifier; > > include!(concat!( > env!("OUT_DIR"), >@@ -56,17 +56,19 @@ impl PseudoElement { > PseudoElementCascadeType::Lazy > } > > /// Whether cascading this pseudo-element makes it inherit all properties, > /// even reset ones. > /// > /// This is used in Servo for anonymous boxes, though it's likely broken. > #[inline] >- pub fn inherits_all(&self) -> bool { false } >+ pub fn inherits_all(&self) -> bool { >+ false >+ } > > /// Whether the pseudo-element should inherit from the default computed > /// values instead of from the parent element. > /// > /// This is not the common thing, but there are some pseudos (namely: > /// ::backdrop), that shouldn't inherit from the parent element. > pub fn inherits_from_default_values(&self) -> bool { > matches!(*self, PseudoElement::Backdrop) >diff --git a/servo/components/style/gecko/rules.rs b/servo/components/style/gecko/rules.rs >index a57314a418cc..5a5d1b380569 100644 >--- a/servo/components/style/gecko/rules.rs >+++ b/servo/components/style/gecko/rules.rs >@@ -2,26 +2,26 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Bindings for CSS Rule objects > > use byteorder::{BigEndian, WriteBytesExt}; > use counter_style::{self, CounterBound}; > use cssparser::UnicodeRange; >-use font_face::{FontDisplay, FontWeight, FontStretch, FontStyle, Source}; >+use font_face::{FontDisplay, FontStretch, FontStyle, FontWeight, Source}; > use gecko_bindings::structs::{self, nsCSSValue}; > use gecko_bindings::sugar::ns_css_value::ToNsCssValue; > use properties::longhands::font_language_override; > use std::str; > use values::computed::font::FamilyName; > use values::generics::font::FontTag; >+use values::specified::font::SpecifiedFontStyle; > use values::specified::font::{AbsoluteFontWeight, FontStretch as SpecifiedFontStretch}; > use values::specified::font::{SpecifiedFontFeatureSettings, SpecifiedFontVariationSettings}; >-use values::specified::font::SpecifiedFontStyle; > > impl<'a> ToNsCssValue for &'a FamilyName { > fn convert(self, nscssvalue: &mut nsCSSValue) { > nscssvalue.set_string_from_atom(&self.name) > } > } > > impl<'a> ToNsCssValue for &'a SpecifiedFontStretch { >@@ -96,17 +96,17 @@ macro_rules! descriptor_range_conversion { > let mut b = nsCSSValue::null(); > > a.set_from(first); > b.set_from(second); > > nscssvalue.set_pair(&a, &b); > } > } >- } >+ }; > } > > descriptor_range_conversion!(FontWeight); > descriptor_range_conversion!(FontStretch); > > impl<'a> ToNsCssValue for &'a FontStyle { > fn convert(self, nscssvalue: &mut nsCSSValue) { > match *self { >@@ -126,17 +126,17 @@ impl<'a> ToNsCssValue for &'a FontStyle { > } > > impl<'a> ToNsCssValue for &'a font_language_override::SpecifiedValue { > fn convert(self, nscssvalue: &mut nsCSSValue) { > match *self { > font_language_override::SpecifiedValue::Normal => nscssvalue.set_normal(), > font_language_override::SpecifiedValue::Override(ref lang) => { > nscssvalue.set_string(&*lang) >- }, >+ } > // This path is unreachable because the descriptor is only specified by the user. > font_language_override::SpecifiedValue::System(_) => unreachable!(), > } > } > } > > impl<'a> ToNsCssValue for &'a Vec<Source> { > fn convert(self, nscssvalue: &mut nsCSSValue) { >@@ -160,20 +160,20 @@ impl<'a> ToNsCssValue for &'a Vec<Source> { > } > for src in self.iter() { > match *src { > Source::Url(ref url) => { > next!().set_url(&url.url); > for hint in url.format_hints.iter() { > next!().set_font_format(&hint); > } >- }, >+ } > Source::Local(ref family) => { > next!().set_local_font(&family.name); >- }, >+ } > } > } > debug_assert!(target_srcs.next().is_none(), "Should have filled all slots"); > } > } > > impl<'a> ToNsCssValue for &'a Vec<UnicodeRange> { > fn convert(self, nscssvalue: &mut nsCSSValue) { >@@ -212,24 +212,24 @@ impl<'a> ToNsCssValue for &'a counter_style::System { > Fixed { > ref first_symbol_value, > } => { > let mut a = nsCSSValue::null(); > let mut b = nsCSSValue::null(); > a.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_FIXED as i32); > b.set_integer(first_symbol_value.map_or(1, |v| v.value())); > nscssvalue.set_pair(&a, &b); >- }, >+ } > Extends(ref other) => { > let mut a = nsCSSValue::null(); > let mut b = nsCSSValue::null(); > a.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_EXTENDS as i32); > b.set_atom_ident(other.0.clone()); > nscssvalue.set_pair(&a, &b); >- }, >+ } > } > } > } > > impl<'a> ToNsCssValue for &'a counter_style::Negative { > fn convert(self, nscssvalue: &mut nsCSSValue) { > if let Some(ref second) = self.1 { > let mut a = nsCSSValue::null(); >diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs >index fa514835e8c7..456ca9e874d9 100644 >--- a/servo/components/style/gecko/selector_parser.rs >+++ b/servo/components/style/gecko/selector_parser.rs >@@ -7,20 +7,20 @@ > use cssparser::{BasicParseError, BasicParseErrorKind, Parser}; > use cssparser::{CowRcStr, SourceLocation, ToCss, Token}; > use element_state::{DocumentState, ElementState}; > use gecko_bindings::structs; > use gecko_bindings::structs::RawServoSelectorList; > use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; > use invalidation::element::document_state::InvalidationMatchingData; > use selector_parser::{Direction, SelectorParser}; >-use selectors::SelectorList; >-use selectors::parser::{SelectorParseErrorKind, Visit}; > use selectors::parser::{self as selector_parser, Selector}; >+use selectors::parser::{SelectorParseErrorKind, Visit}; > use selectors::visitor::SelectorVisitor; >+use selectors::SelectorList; > use std::fmt; > use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss as ToCss_}; > use thin_slice::ThinBoxedSlice; > > pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, PSEUDO_COUNT}; > pub use gecko::snapshot::SnapshotMap; > >@@ -189,19 +189,18 @@ impl NonTSPseudoClass { > NonTSPseudoClass::Fullscreen => unsafe { > mozilla::StaticPrefs_sVarCache_full_screen_api_unprefix_enabled > }, > NonTSPseudoClass::Defined => unsafe { > structs::nsContentUtils_sIsCustomElementsEnabled > }, > // Otherwise, a pseudo-class is enabled in content when it > // doesn't have any enabled flag. >- _ => !self.has_any_flag( >- NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME, >- ), >+ _ => !self >+ .has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME), > } > } > > /// <https://drafts.csswg.org/selectors-4/#useraction-pseudos> > /// > /// We intentionally skip the link-related ones. > pub fn is_safe_user_action_state(&self) -> bool { > matches!( >@@ -242,18 +241,17 @@ impl NonTSPseudoClass { > NonTSPseudoClass::MozWindowInactive => DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE, > _ => DocumentState::empty(), > } > } > > /// Returns true if the given pseudoclass should trigger style sharing cache > /// revalidation. > pub fn needs_cache_revalidation(&self) -> bool { >- self.state_flag().is_empty() && >- !matches!(*self, >+ self.state_flag().is_empty() && !matches!(*self, > // :-moz-any is handled by the revalidation visitor walking > // the things inside it; it does not need to cause > // revalidation on its own. > NonTSPseudoClass::MozAny(_) | > // :dir() depends on state only, but doesn't use state_flag > // because its semantics don't quite match. Nevertheless, it > // doesn't need cache revalidation, because we already compare > // states for elements and candidates. >@@ -277,18 +275,19 @@ impl NonTSPseudoClass { > ) > } > > /// Returns true if the evaluation of the pseudo-class depends on the > /// element's attributes. > pub fn is_attr_based(&self) -> bool { > matches!( > *self, >- NonTSPseudoClass::MozTableBorderNonzero | NonTSPseudoClass::MozBrowserFrame | >- NonTSPseudoClass::Lang(..) >+ NonTSPseudoClass::MozTableBorderNonzero >+ | NonTSPseudoClass::MozBrowserFrame >+ | NonTSPseudoClass::Lang(..) > ) > } > } > > impl ::selectors::parser::NonTSPseudoClass for NonTSPseudoClass { > type Impl = SelectorImpl; > > #[inline] >@@ -317,24 +316,24 @@ impl ::selectors::SelectorImpl for SelectorImpl { > } > > impl<'a> SelectorParser<'a> { > fn is_pseudo_class_enabled(&self, pseudo_class: &NonTSPseudoClass) -> bool { > if pseudo_class.is_enabled_in_content() { > return true; > } > >- if self.in_user_agent_stylesheet() && >- pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS) >+ if self.in_user_agent_stylesheet() >+ && pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_UA_SHEETS) > { > return true; > } > >- if self.chrome_rules_enabled() && >- pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_CHROME) >+ if self.chrome_rules_enabled() >+ && pseudo_class.has_any_flag(NonTSPseudoClassFlag::PSEUDO_CLASS_ENABLED_IN_CHROME) > { > return true; > } > > return false; > } > > fn is_pseudo_element_enabled(&self, pseudo_element: &PseudoElement) -> bool { >@@ -472,17 +471,17 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { > if name.starts_with("-moz-tree-") { > // Tree pseudo-elements can have zero or more arguments, separated > // by either comma or space. > let mut args = Vec::new(); > loop { > let location = parser.current_source_location(); > match parser.next() { > Ok(&Token::Ident(ref ident)) => args.push(Atom::from(ident.as_ref())), >- Ok(&Token::Comma) => {}, >+ Ok(&Token::Comma) => {} > Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), > Err(BasicParseError { > kind: BasicParseErrorKind::EndOfInput, > .. > }) => break, > _ => unreachable!("Parser::next() shouldn't return any other error"), > } > } >diff --git a/servo/components/style/gecko/snapshot.rs b/servo/components/style/gecko/snapshot.rs >index fc4a9121ae40..6b6266dce6e6 100644 >--- a/servo/components/style/gecko/snapshot.rs >+++ b/servo/components/style/gecko/snapshot.rs >@@ -1,28 +1,28 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A gecko snapshot, that stores the element attributes and state before they > //! change in order to properly calculate restyle hints. > >-use WeakAtom; > use dom::TElement; > use element_state::ElementState; > use gecko::snapshot_helpers; > use gecko::wrapper::{GeckoElement, NamespaceConstraintHelpers}; > use gecko_bindings::bindings; > use gecko_bindings::structs::ServoElementSnapshot; > use gecko_bindings::structs::ServoElementSnapshotFlags as Flags; > use gecko_bindings::structs::ServoElementSnapshotTable; > use invalidation::element::element_wrapper::ElementSnapshot; > use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator}; > use selectors::attr::{CaseSensitivity, NamespaceConstraint}; > use string_cache::{Atom, Namespace}; >+use WeakAtom; > > /// A snapshot of a Gecko element. > pub type GeckoElementSnapshot = ServoElementSnapshot; > > /// A map from elements to snapshots for Gecko's style back-end. > pub type SnapshotMap = ServoElementSnapshotTable; > > impl SnapshotMap { >@@ -83,17 +83,17 @@ impl GeckoElementSnapshot { > ns: &NamespaceConstraint<&Namespace>, > local_name: &Atom, > operation: &AttrSelectorOperation<&Atom>, > ) -> bool { > unsafe { > match *operation { > AttrSelectorOperation::Exists => { > bindings::Gecko_SnapshotHasAttr(self, ns.atom_or_null(), local_name.as_ptr()) >- }, >+ } > AttrSelectorOperation::WithValue { > operator, > case_sensitivity, > expected_value, > } => { > let ignore_case = match case_sensitivity { > CaseSensitivity::CaseSensitive => false, > CaseSensitivity::AsciiCaseInsensitive => true, >@@ -138,19 +138,19 @@ impl GeckoElementSnapshot { > AttrSelectorOperator::Substring => { > bindings::Gecko_SnapshotAttrHasSubstring( > self, > ns.atom_or_null(), > local_name.as_ptr(), > expected_value.as_ptr(), > ignore_case, > ) >- }, >+ } > } >- }, >+ } > } > } > } > } > > impl ElementSnapshot for GeckoElementSnapshot { > fn debug_list_attributes(&self) -> String { > use nsstring::nsCString; >diff --git a/servo/components/style/gecko/snapshot_helpers.rs b/servo/components/style/gecko/snapshot_helpers.rs >index 6c40f242d5f0..1b8ba9735fc5 100644 >--- a/servo/components/style/gecko/snapshot_helpers.rs >+++ b/servo/components/style/gecko/snapshot_helpers.rs >@@ -1,19 +1,19 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Element an snapshot common logic. > >-use CaseSensitivityExt; > use gecko_bindings::bindings; > use gecko_bindings::structs::{self, nsAtom}; > use selectors::attr::CaseSensitivity; > use string_cache::{Atom, WeakAtom}; >+use CaseSensitivityExt; > > /// A function that, given an element of type `T`, allows you to get a single > /// class or a class list. > enum Class<'a> { > None, > One(*const nsAtom), > More(&'a [structs::RefPtr<nsAtom>]), > } >@@ -36,35 +36,47 @@ unsafe fn get_class_from_attr(attr: &structs::nsAttrValue) -> Class { > return Class::None; > } > if base_type == structs::nsAttrValue_ValueBaseType_eAtomBase { > return Class::One(ptr::<nsAtom>(attr)); > } > debug_assert_eq!(base_type, structs::nsAttrValue_ValueBaseType_eOtherBase); > > let container = ptr::<structs::MiscContainer>(attr); >- debug_assert_eq!((*container).mType, structs::nsAttrValue_ValueType_eAtomArray); >- let array = >- (*container).__bindgen_anon_1.mValue.as_ref().__bindgen_anon_1.mAtomArray.as_ref(); >+ debug_assert_eq!( >+ (*container).mType, >+ structs::nsAttrValue_ValueType_eAtomArray >+ ); >+ let array = (*container) >+ .__bindgen_anon_1 >+ .mValue >+ .as_ref() >+ .__bindgen_anon_1 >+ .mAtomArray >+ .as_ref(); > Class::More(&***array) > } > > #[inline(always)] > unsafe fn get_id_from_attr(attr: &structs::nsAttrValue) -> &WeakAtom { >- debug_assert_eq!(base_type(attr), structs::nsAttrValue_ValueBaseType_eAtomBase); >+ debug_assert_eq!( >+ base_type(attr), >+ structs::nsAttrValue_ValueBaseType_eAtomBase >+ ); > WeakAtom::new(ptr::<nsAtom>(attr)) > } > > /// Find an attribute value with a given name and no namespace. > #[inline(always)] > pub fn find_attr<'a>( > attrs: &'a [structs::AttrArray_InternalAttr], > name: &Atom, > ) -> Option<&'a structs::nsAttrValue> { >- attrs.iter() >+ attrs >+ .iter() > .find(|attr| attr.mName.mBits == name.as_ptr() as usize) > .map(|attr| &attr.mValue) > } > > /// Finds the id attribute from a list of attributes. > #[inline(always)] > pub fn get_id(attrs: &[structs::AttrArray_InternalAttr]) -> Option<&WeakAtom> { > Some(unsafe { get_id_from_attr(find_attr(attrs, &atom!("id"))?) }) >@@ -75,42 +87,40 @@ pub fn get_id(attrs: &[structs::AttrArray_InternalAttr]) -> Option<&WeakAtom> { > #[inline(always)] > pub fn has_class( > name: &Atom, > case_sensitivity: CaseSensitivity, > attr: &structs::nsAttrValue, > ) -> bool { > match unsafe { get_class_from_attr(attr) } { > Class::None => false, >- Class::One(atom) => unsafe { >- case_sensitivity.eq_atom(name, WeakAtom::new(atom)) >+ Class::One(atom) => unsafe { case_sensitivity.eq_atom(name, WeakAtom::new(atom)) }, >+ Class::More(atoms) => match case_sensitivity { >+ CaseSensitivity::CaseSensitive => { >+ atoms.iter().any(|atom| atom.mRawPtr == name.as_ptr()) >+ } >+ CaseSensitivity::AsciiCaseInsensitive => unsafe { >+ atoms >+ .iter() >+ .any(|atom| WeakAtom::new(atom.mRawPtr).eq_ignore_ascii_case(name)) >+ }, > }, >- Class::More(atoms) => { >- match case_sensitivity { >- CaseSensitivity::CaseSensitive => { >- atoms.iter().any(|atom| atom.mRawPtr == name.as_ptr()) >- } >- CaseSensitivity::AsciiCaseInsensitive => unsafe { >- atoms.iter().any(|atom| WeakAtom::new(atom.mRawPtr).eq_ignore_ascii_case(name)) >- } >- } >- } > } > } > > /// Given an item, a callback, and a getter, execute `callback` for each class > /// this `item` has. > #[inline(always)] > pub fn each_class<F>(attr: &structs::nsAttrValue, mut callback: F) > where > F: FnMut(&Atom), > { > unsafe { > match get_class_from_attr(attr) { >- Class::None => {}, >+ Class::None => {} > Class::One(atom) => Atom::with(atom, callback), > Class::More(atoms) => { > for atom in atoms { > Atom::with(atom.mRawPtr, &mut callback) > } > } > } > } >diff --git a/servo/components/style/gecko/url.rs b/servo/components/style/gecko/url.rs >index b94d21397648..de1889d4b403 100644 >--- a/servo/components/style/gecko/url.rs >+++ b/servo/components/style/gecko/url.rs >@@ -1,20 +1,20 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Common handling for the specified value CSS url() values. > > use cssparser::Parser; > use gecko_bindings::bindings; >-use gecko_bindings::structs::ServoBundledURI; > use gecko_bindings::structs::mozilla::css::URLValueData; >-use gecko_bindings::structs::root::{RustString, nsStyleImageRequest}; > use gecko_bindings::structs::root::mozilla::css::{ImageValue, URLValue}; >+use gecko_bindings::structs::root::{nsStyleImageRequest, RustString}; >+use gecko_bindings::structs::ServoBundledURI; > use gecko_bindings::sugar::refptr::RefPtr; > use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; > use nsstring::nsCString; > use parser::{Parse, ParserContext}; > use servo_arc::{Arc, RawOffsetArc}; > use std::fmt::{self, Write}; > use std::mem; > use style_traits::{CssWriter, ParseError, ToCss}; >@@ -50,18 +50,17 @@ impl CssUrl { > /// URLs in gecko, so we just return false here. > /// use its |resolved| status. > pub fn is_invalid(&self) -> bool { > false > } > > /// Convert from URLValueData to SpecifiedUrl. > unsafe fn from_url_value_data(url: &URLValueData) -> Self { >- let arc_type = >- &url.mString as *const _ as *const RawOffsetArc<String>; >+ let arc_type = &url.mString as *const _ as *const RawOffsetArc<String>; > CssUrl { > serialization: Arc::from_raw_offset((*arc_type).clone()), > extra_data: UrlExtraData(url.mExtraData.to_safe()), > } > } > > /// Returns true if this URL looks like a fragment. > /// See https://drafts.csswg.org/css-values/#local-urls >@@ -135,17 +134,16 @@ impl SpecifiedUrl { > // We do not expect Gecko_NewURLValue returns null. > debug_assert!(!ptr.is_null()); > RefPtr::from_addrefed(ptr) > }; > Self { url, url_value } > } > } > >- > impl PartialEq for SpecifiedUrl { > fn eq(&self, other: &Self) -> bool { > self.url.eq(&other.url) > } > } > > impl Eq for SpecifiedUrl {} > >@@ -250,20 +248,17 @@ impl ToComputedValue for SpecifiedImageUrl { > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > computed.0.clone() > } > } > >-fn serialize_computed_url<W>( >- url_value_data: &URLValueData, >- dest: &mut CssWriter<W>, >-) -> fmt::Result >+fn serialize_computed_url<W>(url_value_data: &URLValueData, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > dest.write_str("url(")?; > unsafe { > let mut string = nsCString::new(); > bindings::Gecko_GetComputedURLSpec(url_value_data, &mut string); > string.as_str_unchecked().to_css(dest)?; >@@ -276,17 +271,17 @@ where > /// The only difference between specified and computed URLs is the > /// serialization. > #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] > pub struct ComputedUrl(pub SpecifiedUrl); > > impl ToCss for ComputedUrl { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where >- W: Write >+ W: Write, > { > serialize_computed_url(&self.0.url_value._base, dest) > } > } > > impl ComputedUrl { > /// Convert from RefPtr<URLValue> to ComputedUrl. > pub unsafe fn from_url_value(url_value: RefPtr<URLValue>) -> Self { >@@ -297,17 +292,17 @@ impl ComputedUrl { > > /// The computed value of a CSS `url()` for image. > #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] > pub struct ComputedImageUrl(pub SpecifiedImageUrl); > > impl ToCss for ComputedImageUrl { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where >- W: Write >+ W: Write, > { > serialize_computed_url(&self.0.image_value._base, dest) > } > } > > impl ComputedImageUrl { > /// Convert from nsStyleImageReques to ComputedImageUrl. > pub unsafe fn from_image_request(image_request: &nsStyleImageRequest) -> Self { >diff --git a/servo/components/style/gecko/values.rs b/servo/components/style/gecko/values.rs >index 3bb22947211d..b2b5ac937f1f 100644 >--- a/servo/components/style/gecko/values.rs >+++ b/servo/components/style/gecko/values.rs >@@ -1,39 +1,41 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #![allow(unsafe_code)] > > //! Different kind of helpers to interact with Gecko values. > >-use Atom; > use app_units::Au; > use counter_style::{Symbol, Symbols}; > use cssparser::RGBA; >-use gecko_bindings::structs::{self, CounterStylePtr, nsStyleCoord}; >+use gecko_bindings::structs::{self, nsStyleCoord, CounterStylePtr}; > use gecko_bindings::structs::{StyleGridTrackBreadth, StyleShapeRadius}; > use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut, CoordDataValue}; > use media_queries::Device; > use nsstring::{nsACString, nsCStr}; > use std::cmp::max; >-use values::{Auto, Either, None_, Normal}; >-use values::computed::{Angle, ExtremumLength, Length, LengthOrPercentage, LengthOrPercentageOrAuto}; >+use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; >+use values::computed::FlexBasis as ComputedFlexBasis; >+use values::computed::{ >+ Angle, ExtremumLength, Length, LengthOrPercentage, LengthOrPercentageOrAuto, >+}; > use values::computed::{LengthOrPercentageOrNone, Number, NumberOrPercentage}; > use values::computed::{MaxLength, MozLength, Percentage}; > use values::computed::{NonNegativeLength, NonNegativeLengthOrPercentage, NonNegativeNumber}; >-use values::computed::FlexBasis as ComputedFlexBasis; >-use values::computed::basic_shape::ShapeRadius as ComputedShapeRadius; >-use values::generics::{CounterStyleOrNone, NonNegative}; > use values::generics::basic_shape::ShapeRadius; > use values::generics::box_::Perspective; > use values::generics::flex::FlexBasis; > use values::generics::gecko::ScrollSnapPoint; > use values::generics::grid::{TrackBreadth, TrackKeyword}; >+use values::generics::{CounterStyleOrNone, NonNegative}; >+use values::{Auto, Either, None_, Normal}; >+use Atom; > > /// A trait that defines an interface to convert from and to `nsStyleCoord`s. > pub trait GeckoStyleCoordConvertible: Sized { > /// Convert this to a `nsStyleCoord`. > fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T); > /// Given a `nsStyleCoord`, try to get a value of this type.. > fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self>; > } >@@ -202,17 +204,17 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrAuto { > }; > coord.set_value(value); > } > > fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { > match coord.as_value() { > CoordDataValue::Coord(coord) => { > Some(LengthOrPercentageOrAuto::Length(Au(coord).into())) >- }, >+ } > CoordDataValue::Percent(p) => Some(LengthOrPercentageOrAuto::Percentage(Percentage(p))), > CoordDataValue::Auto => Some(LengthOrPercentageOrAuto::Auto), > CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrAuto::Calc(calc.into())), > _ => None, > } > } > } > >@@ -226,17 +228,17 @@ impl GeckoStyleCoordConvertible for LengthOrPercentageOrNone { > }; > coord.set_value(value); > } > > fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { > match coord.as_value() { > CoordDataValue::Coord(coord) => { > Some(LengthOrPercentageOrNone::Length(Au(coord).into())) >- }, >+ } > CoordDataValue::Percent(p) => Some(LengthOrPercentageOrNone::Percentage(Percentage(p))), > CoordDataValue::None => Some(LengthOrPercentageOrNone::None), > CoordDataValue::Calc(calc) => Some(LengthOrPercentageOrNone::Calc(calc.into())), > _ => None, > } > } > } > >@@ -262,17 +264,17 @@ impl<L: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for TrackBreadth< > CoordDataValue::Enumerated(v) => { > if v == StyleGridTrackBreadth::MinContent as u32 { > Some(TrackBreadth::Keyword(TrackKeyword::MinContent)) > } else if v == StyleGridTrackBreadth::MaxContent as u32 { > Some(TrackBreadth::Keyword(TrackKeyword::MaxContent)) > } else { > None > } >- }, >+ } > CoordDataValue::FlexFraction(fr) => Some(TrackBreadth::Fr(fr)), > CoordDataValue::Auto => Some(TrackBreadth::Keyword(TrackKeyword::Auto)), > _ => L::from_gecko_style_coord(coord).map(TrackBreadth::Breadth), > }) > } > } > > impl GeckoStyleCoordConvertible for ComputedShapeRadius { >@@ -293,17 +295,17 @@ impl GeckoStyleCoordConvertible for ComputedShapeRadius { > CoordDataValue::Enumerated(v) => { > if v == StyleShapeRadius::ClosestSide as u32 { > Some(ShapeRadius::ClosestSide) > } else if v == StyleShapeRadius::FarthestSide as u32 { > Some(ShapeRadius::FarthestSide) > } else { > None > } >- }, >+ } > _ => LengthOrPercentage::from_gecko_style_coord(coord).map(ShapeRadius::Length), > } > } > } > > impl<T: GeckoStyleCoordConvertible> GeckoStyleCoordConvertible for Option<T> { > fn to_gecko_style_coord<U: CoordDataMut>(&self, coord: &mut U) { > if let Some(ref me) = *self { >@@ -389,26 +391,26 @@ impl GeckoStyleCoordConvertible for ExtremumLength { > } > > fn from_gecko_style_coord<T: CoordData>(coord: &T) -> Option<Self> { > use gecko_bindings::structs::{NS_STYLE_WIDTH_AVAILABLE, NS_STYLE_WIDTH_FIT_CONTENT}; > use gecko_bindings::structs::{NS_STYLE_WIDTH_MAX_CONTENT, NS_STYLE_WIDTH_MIN_CONTENT}; > match coord.as_value() { > CoordDataValue::Enumerated(NS_STYLE_WIDTH_MAX_CONTENT) => { > Some(ExtremumLength::MozMaxContent) >- }, >+ } > CoordDataValue::Enumerated(NS_STYLE_WIDTH_MIN_CONTENT) => { > Some(ExtremumLength::MozMinContent) >- }, >+ } > CoordDataValue::Enumerated(NS_STYLE_WIDTH_FIT_CONTENT) => { > Some(ExtremumLength::MozFitContent) >- }, >+ } > CoordDataValue::Enumerated(NS_STYLE_WIDTH_AVAILABLE) => { > Some(ExtremumLength::MozAvailable) >- }, >+ } > _ => None, > } > } > } > > impl GeckoStyleCoordConvertible for MozLength { > fn to_gecko_style_coord<T: CoordDataMut>(&self, coord: &mut T) { > match *self { >@@ -483,18 +485,20 @@ where > return Some(Perspective::None); > } > Some(Perspective::Length(L::from_gecko_style_coord(coord)?)) > } > } > > /// Convert a given RGBA value to `nscolor`. > pub fn convert_rgba_to_nscolor(rgba: &RGBA) -> u32 { >- ((rgba.alpha as u32) << 24) | ((rgba.blue as u32) << 16) | ((rgba.green as u32) << 8) | >- (rgba.red as u32) >+ ((rgba.alpha as u32) << 24) >+ | ((rgba.blue as u32) << 16) >+ | ((rgba.green as u32) << 8) >+ | (rgba.red as u32) > } > > /// Convert a given `nscolor` to a Servo RGBA value. > pub fn convert_nscolor_to_rgba(color: u32) -> RGBA { > RGBA::new( > (color & 0xff) as u8, > (color >> 8 & 0xff) as u8, > (color >> 16 & 0xff) as u8, >@@ -532,39 +536,38 @@ impl CounterStyleOrNone { > }, > CounterStyleOrNone::Symbols(symbols_type, symbols) => { > let symbols: Vec<_> = symbols > .0 > .iter() > .map(|symbol| match *symbol { > Symbol::String(ref s) => nsCStr::from(s), > Symbol::Ident(_) => unreachable!("Should not have identifier in symbols()"), >- }) >- .collect(); >+ }).collect(); > let symbols: Vec<_> = symbols > .iter() > .map(|symbol| symbol as &nsACString as *const _) > .collect(); > unsafe { > set_symbols( > gecko_value, > symbols_type.to_gecko_keyword(), > symbols.as_ptr(), > symbols.len() as u32, > ) > }; >- }, >+ } > } > } > > /// Convert Gecko CounterStylePtr to CounterStyleOrNone or String. > pub fn from_gecko_value(gecko_value: &CounterStylePtr) -> Either<Self, String> { > use gecko_bindings::bindings; >- use values::CustomIdent; > use values::generics::SymbolsType; >+ use values::CustomIdent; > > let name = unsafe { bindings::Gecko_CounterStyle_GetName(gecko_value) }; > if !name.is_null() { > let name = unsafe { Atom::from_raw(name) }; > if name == atom!("none") { > Either::First(CounterStyleOrNone::None) > } else { > Either::First(CounterStyleOrNone::Name(CustomIdent(name))) >diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs >index 1ba850696d15..d81bab247395 100644 >--- a/servo/components/style/gecko/wrapper.rs >+++ b/servo/components/style/gecko/wrapper.rs >@@ -9,88 +9,89 @@ > //! > //! This really follows the Servo pattern in > //! `components/script/layout_wrapper.rs`. > //! > //! This theoretically should live in its own crate, but now it lives in the > //! style system it's kind of pointless in the Stylo case, and only Servo forces > //! the separation between the style system implementation and everything else. > >-use CaseSensitivityExt; > use app_units::Au; > use applicable_declarations::ApplicableDeclarationBlock; > use atomic_refcell::{AtomicRefCell, AtomicRefMut}; > use author_styles::AuthorStyles; > use context::{PostAnimationTasks, QuirksMode, SharedStyleContext, UpdateAnimationsTasks}; > use data::ElementData; > use dom::{LayoutIterator, NodeInfo, OpaqueNode, TDocument, TElement, TNode, TShadowRoot}; > use element_state::{DocumentState, ElementState}; > use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult}; > use gecko::data::GeckoStyleSheet; > use gecko::global_style_data::GLOBAL_STYLE_DATA; > use gecko::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl}; > use gecko::snapshot_helpers; > use gecko_bindings::bindings; >-use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme}; >-use gecko_bindings::bindings::{Gecko_GetLastChild, Gecko_GetPreviousSibling, Gecko_GetNextStyleChild}; >-use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; > use gecko_bindings::bindings::Gecko_ElementHasAnimations; > use gecko_bindings::bindings::Gecko_ElementHasCSSAnimations; > use gecko_bindings::bindings::Gecko_ElementHasCSSTransitions; > use gecko_bindings::bindings::Gecko_GetActiveLinkAttrDeclarationBlock; > use gecko_bindings::bindings::Gecko_GetAnimationEffectCount; > use gecko_bindings::bindings::Gecko_GetAnimationRule; > use gecko_bindings::bindings::Gecko_GetExtraContentStyleDeclarations; > use gecko_bindings::bindings::Gecko_GetHTMLPresentationAttrDeclarationBlock; > use gecko_bindings::bindings::Gecko_GetStyleAttrDeclarationBlock; > use gecko_bindings::bindings::Gecko_GetUnvisitedLinkAttrDeclarationBlock; > use gecko_bindings::bindings::Gecko_GetVisitedLinkAttrDeclarationBlock; > use gecko_bindings::bindings::Gecko_IsSignificantChild; > use gecko_bindings::bindings::Gecko_MatchLang; > use gecko_bindings::bindings::Gecko_UnsetDirtyStyleAttr; > use gecko_bindings::bindings::Gecko_UpdateAnimations; >+use gecko_bindings::bindings::{Gecko_ElementState, Gecko_GetDocumentLWTheme}; >+use gecko_bindings::bindings::{ >+ Gecko_GetLastChild, Gecko_GetNextStyleChild, Gecko_GetPreviousSibling, >+}; >+use gecko_bindings::bindings::{Gecko_SetNodeFlags, Gecko_UnsetNodeFlags}; > use gecko_bindings::structs; >-use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding}; >-use gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; >+use gecko_bindings::structs::nsChangeHint; >+use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme; >+use gecko_bindings::structs::nsRestyleHint; >+use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; > use gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT; > use gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO; > use gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO; > use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT; >-use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel; > use gecko_bindings::structs::NODE_DESCENDANTS_NEED_FRAMES; > use gecko_bindings::structs::NODE_NEEDS_FRAME; >-use gecko_bindings::structs::nsChangeHint; >-use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme; >-use gecko_bindings::structs::nsRestyleHint; >+use gecko_bindings::structs::{nsAtom, nsIContent, nsINode_BooleanFlag}; >+use gecko_bindings::structs::{RawGeckoElement, RawGeckoNode, RawGeckoXBLBinding}; > use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI}; > use hash::FxHashMap; > use logical_geometry::WritingMode; > use media_queries::Device; >-use properties::{ComputedValues, LonghandId}; >-use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; > use properties::animated_properties::{AnimationValue, AnimationValueMap}; > use properties::style_structs::Font; >+use properties::{ComputedValues, LonghandId}; >+use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock}; > use rule_tree::CascadeLevel as ServoCascadeLevel; > use selector_parser::{AttrValue, Direction, PseudoClassStringArg}; >-use selectors::{Element, OpaqueElement}; > use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator}; > use selectors::attr::{CaseSensitivity, NamespaceConstraint}; >-use selectors::matching::{ElementSelectorFlags, MatchingContext}; > use selectors::matching::VisitedHandlingMode; >+use selectors::matching::{ElementSelectorFlags, MatchingContext}; > use selectors::sink::Push; >+use selectors::{Element, OpaqueElement}; > use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; > use shared_lock::Locked; > use std::cell::RefCell; > use std::fmt; > use std::hash::{Hash, Hasher}; > use std::mem; > use std::ptr; > use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; > use stylist::CascadeData; >- >+use CaseSensitivityExt; > > #[inline] > fn elements_with_id<'a, 'le>( > array: *const structs::nsTArray<*mut RawGeckoElement>, > ) -> &'a [GeckoElement<'le>] { > unsafe { > if array.is_null() { > return &[]; >@@ -173,23 +174,22 @@ impl<'lr> TShadowRoot for GeckoShadowRoot<'lr> { > { > debug_assert!(!self.0.mServoStyles.mPtr.is_null()); > > let author_styles = unsafe { > &*(self.0.mServoStyles.mPtr as *const structs::RawServoAuthorStyles > as *const bindings::RawServoAuthorStyles) > }; > >- > let author_styles = AuthorStyles::<GeckoStyleSheet>::from_ffi(author_styles); > > debug_assert!( >- author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() || >- author_styles.stylesheets.is_empty() || >- author_styles.stylesheets.dirty() >+ author_styles.quirks_mode == self.as_node().owner_doc().quirks_mode() >+ || author_styles.stylesheets.is_empty() >+ || author_styles.stylesheets.dirty() > ); > > &author_styles.data > } > > #[inline] > fn elements_with_id<'a>(&self, id: &Atom) -> Result<&'a [GeckoElement<'lr>], ()> > where >@@ -302,18 +302,18 @@ impl<'ln> GeckoNode<'ln> { > use gecko_bindings::structs::*; > let flags = self.flags(); > if flags & (NODE_MAY_BE_IN_BINDING_MNGR as u32 | NODE_IS_IN_SHADOW_TREE as u32) != 0 { > return false; > } > > let parent = unsafe { self.0.mParent.as_ref() }.map(GeckoNode); > let parent_el = parent.and_then(|p| p.as_element()); >- if flags & (NODE_IS_NATIVE_ANONYMOUS_ROOT as u32) != 0 && >- parent_el.map_or(false, |el| el.is_root()) >+ if flags & (NODE_IS_NATIVE_ANONYMOUS_ROOT as u32) != 0 >+ && parent_el.map_or(false, |el| el.is_root()) > { > return false; > } > > if let Some(parent) = parent_el { > if parent.shadow_root().is_some() || parent.xbl_binding().is_some() { > return false; > } >@@ -371,17 +371,18 @@ impl<'ln> TNode for GeckoNode<'ln> { > fn parent_node(&self) -> Option<Self> { > unsafe { self.0.mParent.as_ref().map(GeckoNode) } > } > > #[inline] > fn first_child(&self) -> Option<Self> { > unsafe { > self.0 >- .mFirstChild.raw::<nsIContent>() >+ .mFirstChild >+ .raw::<nsIContent>() > .as_ref() > .map(GeckoNode::from_content) > } > } > > #[inline] > fn last_child(&self) -> Option<Self> { > unsafe { Gecko_GetLastChild(self.0).map(GeckoNode) } >@@ -391,17 +392,18 @@ impl<'ln> TNode for GeckoNode<'ln> { > fn prev_sibling(&self) -> Option<Self> { > unsafe { Gecko_GetPreviousSibling(self.0).map(GeckoNode) } > } > > #[inline] > fn next_sibling(&self) -> Option<Self> { > unsafe { > self.0 >- .mNextSibling.raw::<nsIContent>() >+ .mNextSibling >+ .raw::<nsIContent>() > .as_ref() > .map(GeckoNode::from_content) > } > } > > #[inline] > fn owner_doc(&self) -> Self::ConcreteDocument { > debug_assert!(!self.node_info().mDocument.is_null()); >@@ -493,17 +495,17 @@ impl<'a> Drop for GeckoChildrenIterator<'a> { > impl<'a> Iterator for GeckoChildrenIterator<'a> { > type Item = GeckoNode<'a>; > fn next(&mut self) -> Option<GeckoNode<'a>> { > match *self { > GeckoChildrenIterator::Current(curr) => { > let next = curr.and_then(|node| node.next_sibling()); > *self = GeckoChildrenIterator::Current(next); > curr >- }, >+ } > GeckoChildrenIterator::GeckoIterator(ref mut it) => unsafe { > // We do this unsafe lengthening of the lifetime here because > // structs::StyleChildrenIterator is actually StyleChildrenIterator<'a>, > // however we can't express this easily with bindgen, and it would > // introduce functions with two input lifetimes into bindgen, > // which would be out of scope for elision. > Gecko_GetNextStyleChild(&mut *(it as *mut _)).map(GeckoNode) > }, >@@ -596,17 +598,17 @@ impl<'le> GeckoElement<'le> { > fn get_class_attr(&self) -> Option<&structs::nsAttrValue> { > if !self.may_have_class() { > return None; > } > > if self.is_svg_element() { > let svg_class = unsafe { bindings::Gecko_GetSVGAnimatedClass(self.0).as_ref() }; > if let Some(c) = svg_class { >- return Some(c) >+ return Some(c); > } > } > > snapshot_helpers::find_attr(self.attrs(), &atom!("class")) > } > > #[inline] > fn closest_anon_subtree_root_parent(&self) -> Option<Self> { >@@ -666,20 +668,19 @@ impl<'le> GeckoElement<'le> { > unsafe { slots.as_ref() } > } > > /// Returns a reference to the extended DOM slots for this Element. > #[inline] > fn extended_slots(&self) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> { > self.dom_slots().and_then(|s| unsafe { > // For the bit usage, see nsContentSlots::GetExtendedSlots. >- let e_slots = s._base.mExtendedSlots & >- !structs::nsIContent_nsContentSlots_sNonOwningExtendedSlotsFlag; >- (e_slots as *const structs::FragmentOrElement_nsExtendedDOMSlots) >- .as_ref() >+ let e_slots = s._base.mExtendedSlots >+ & !structs::nsIContent_nsContentSlots_sNonOwningExtendedSlotsFlag; >+ (e_slots as *const structs::FragmentOrElement_nsExtendedDOMSlots).as_ref() > }) > } > > #[inline] > fn may_be_in_binding_manager(&self) -> bool { > self.flags() & (structs::NODE_MAY_BE_IN_BINDING_MNGR as u32) != 0 > } > >@@ -715,45 +716,46 @@ impl<'le> GeckoElement<'le> { > // rather than in slots. So just get it through FFI for now. > unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } > } else { > let binding_parent = unsafe { self.non_xul_xbl_binding_parent_raw_content().as_ref() } > .map(GeckoNode::from_content) > .and_then(|n| n.as_element()); > > debug_assert!( >- binding_parent == unsafe { >- bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) >- } >+ binding_parent >+ == unsafe { bindings::Gecko_GetBindingParent(self.0).map(GeckoElement) } > ); > binding_parent > } > } > > #[inline] > fn non_xul_xbl_binding_parent_raw_content(&self) -> *mut nsIContent { > debug_assert!(!self.is_xul_element()); >- self.extended_slots() >- .map_or(ptr::null_mut(), |slots| slots._base.mBindingParent.raw::<nsIContent>()) >+ self.extended_slots().map_or(ptr::null_mut(), |slots| { >+ slots._base.mBindingParent.raw::<nsIContent>() >+ }) > } > > #[inline] > fn namespace_id(&self) -> i32 { > self.as_node().node_info().mInner.mNamespaceID > } > > #[inline] > fn has_id(&self) -> bool { > self.as_node() > .get_bool_flag(nsINode_BooleanFlag::ElementHasID) > } > > #[inline] > fn state_internal(&self) -> u64 { >- if !self.as_node() >+ if !self >+ .as_node() > .get_bool_flag(nsINode_BooleanFlag::ElementHasLockedStyleStates) > { > return self.0.mState.mStates; > } > unsafe { Gecko_ElementState(self.0) } > } > > #[inline] >@@ -822,17 +824,17 @@ impl<'le> GeckoElement<'le> { > "Animation restyle hints should not appear with non-animation restyle hints" > ); > > let mut data = match self.mutate_data() { > Some(d) => d, > None => { > debug!("(Element not styled, discarding hints)"); > return; >- }, >+ } > }; > > debug_assert!(data.has_styles(), "how?"); > > // Propagate the bit up the chain. > if restyle_hint.has_animation_hint() { > bindings::Gecko_NoteAnimationOnlyDirtyElement(self.0); > } else { >@@ -874,19 +876,17 @@ impl<'le> GeckoElement<'le> { > > /// Returns true if this node is the shadow root of an use-element shadow tree. > #[inline] > fn is_root_of_use_element_shadow_tree(&self) -> bool { > if !self.as_node().is_in_shadow_tree() { > return false; > } > match self.containing_shadow_host() { >- Some(e) => { >- e.is_svg_element() && e.local_name() == &*local_name!("use") >- }, >+ Some(e) => e.is_svg_element() && e.local_name() == &*local_name!("use"), > None => false, > } > } > > fn css_transitions_info(&self) -> FxHashMap<LonghandId, Arc<AnimationValue>> { > use gecko_bindings::bindings::Gecko_ElementTransitions_EndValueAt; > use gecko_bindings::bindings::Gecko_ElementTransitions_Length; > >@@ -930,23 +930,22 @@ impl<'le> GeckoElement<'le> { > return ***existing != after_value; > } > > let from = AnimationValue::from_computed_values(longhand_id, before_change_style); > let to = AnimationValue::from_computed_values(longhand_id, after_change_style); > > debug_assert_eq!(to.is_some(), from.is_some()); > >- combined_duration > 0.0f32 && from != to && >- from.unwrap() >- .animate( >- to.as_ref().unwrap(), >- Procedure::Interpolate { progress: 0.5 }, >- ) >- .is_ok() >+ combined_duration > 0.0f32 && from != to && from >+ .unwrap() >+ .animate( >+ to.as_ref().unwrap(), >+ Procedure::Interpolate { progress: 0.5 }, >+ ).is_ok() > } > } > > /// Converts flags from the layout used by rust-selectors to the layout used > /// by Gecko. We could align these and then do this without conditionals, but > /// it's probably not worth the trouble. > fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 { > use gecko_bindings::structs::*; >@@ -976,17 +975,19 @@ fn get_animation_rule( > > // There's a very rough correlation between the number of effects > // (animations) on an element and the number of properties it is likely to > // animate, so we use that as an initial guess for the size of the > // AnimationValueMap in order to reduce the number of re-allocations needed. > let effect_count = unsafe { Gecko_GetAnimationEffectCount(element.0) }; > // Also, we should try to reuse the PDB, to avoid creating extra rule nodes. > let mut animation_values = AnimationValueMap::with_capacity_and_hasher( >- effect_count.min(ANIMATABLE_PROPERTY_COUNT), Default::default()); >+ effect_count.min(ANIMATABLE_PROPERTY_COUNT), >+ Default::default(), >+ ); > if unsafe { > Gecko_GetAnimationRule( > element.0, > cascade_level, > AnimationValueMap::as_ffi_mut(&mut animation_values), > ) > } { > let shared_lock = &GLOBAL_STYLE_DATA.shared_lock; >@@ -1080,30 +1081,34 @@ impl structs::FontSizePrefs { > > impl<'le> TElement for GeckoElement<'le> { > type ConcreteNode = GeckoNode<'le>; > type FontMetricsProvider = GeckoFontMetricsProvider; > type TraversalChildrenIterator = GeckoChildrenIterator<'le>; > > fn inheritance_parent(&self) -> Option<Self> { > if self.implemented_pseudo_element().is_some() { >- return self.pseudo_element_originating_element() >+ return self.pseudo_element_originating_element(); > } > >- self.as_node().flattened_tree_parent().and_then(|n| n.as_element()) >+ self.as_node() >+ .flattened_tree_parent() >+ .and_then(|n| n.as_element()) > } > > fn traversal_children(&self) -> LayoutIterator<GeckoChildrenIterator<'le>> { > // This condition is similar to the check that > // StyleChildrenIterator::IsNeeded does, except that it might return > // true if we used to (but no longer) have anonymous content from > // ::before/::after, XBL bindings, or nsIAnonymousContentCreators. >- if self.is_in_anonymous_subtree() || self.has_xbl_binding_with_content() || >- self.is_html_slot_element() || self.shadow_root().is_some() || >- self.may_have_anonymous_children() >+ if self.is_in_anonymous_subtree() >+ || self.has_xbl_binding_with_content() >+ || self.is_html_slot_element() >+ || self.shadow_root().is_some() >+ || self.may_have_anonymous_children() > { > unsafe { > let mut iter: structs::StyleChildrenIterator = ::std::mem::zeroed(); > bindings::Gecko_ConstructStyleChildrenIterator(self.0, &mut iter); > return LayoutIterator(GeckoChildrenIterator::GeckoIterator(iter)); > } > } > >@@ -1153,27 +1158,26 @@ impl<'le> TElement for GeckoElement<'le> { > } > > // FIXME(emilio): Workaround a bindgen bug on Android that causes > // mAssignedNodes to be at the wrong offset. See bug 1466406. > // > // Bug 1466580 tracks running the Android layout tests on automation. > // > // The actual bindgen bug still needs reduction. >- let assigned_nodes: &[structs::RefPtr<structs::nsINode>] = >- if !cfg!(target_os = "android") { >- debug_assert_eq!( >- unsafe { bindings::Gecko_GetAssignedNodes(self.0) }, >- &slot.mAssignedNodes as *const _, >- ); >+ let assigned_nodes: &[structs::RefPtr<structs::nsINode>] = if !cfg!(target_os = "android") { >+ debug_assert_eq!( >+ unsafe { bindings::Gecko_GetAssignedNodes(self.0) }, >+ &slot.mAssignedNodes as *const _, >+ ); > >- &*slot.mAssignedNodes >- } else { >- unsafe { &**bindings::Gecko_GetAssignedNodes(self.0) } >- }; >+ &*slot.mAssignedNodes >+ } else { >+ unsafe { &**bindings::Gecko_GetAssignedNodes(self.0) } >+ }; > > debug_assert_eq!( > mem::size_of::<structs::RefPtr<structs::nsINode>>(), > mem::size_of::<Self::ConcreteNode>(), > "Bad cast!" > ); > > unsafe { mem::transmute(assigned_nodes) } >@@ -1235,21 +1239,20 @@ impl<'le> TElement for GeckoElement<'le> { > } > > #[inline] > fn as_node(&self) -> Self::ConcreteNode { > unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } > } > > fn owner_doc_matches_for_testing(&self, device: &Device) -> bool { >- self.as_node().owner_doc().0 as *const structs::nsIDocument == >- device >- .pres_context() >- .mDocument >- .raw::<structs::nsIDocument>() >+ self.as_node().owner_doc().0 as *const structs::nsIDocument == device >+ .pres_context() >+ .mDocument >+ .raw::<structs::nsIDocument>() > } > > fn style_attribute(&self) -> Option<ArcBorrow<Locked<PropertyDeclarationBlock>>> { > if !self.may_have_style_attribute() { > return None; > } > > let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; >@@ -1363,28 +1366,29 @@ impl<'le> TElement for GeckoElement<'le> { > } > > unsafe fn unset_animation_only_dirty_descendants(&self) { > self.unset_flags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32) > } > > unsafe fn clear_descendant_bits(&self) { > self.unset_flags( >- ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 | >- ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 | >- NODE_DESCENDANTS_NEED_FRAMES as u32, >+ ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 >+ | ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 >+ | NODE_DESCENDANTS_NEED_FRAMES as u32, > ) > } > > #[inline] > unsafe fn clear_dirty_bits(&self) { > self.unset_flags( >- ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 | >- ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 | >- NODE_DESCENDANTS_NEED_FRAMES as u32 | NODE_NEEDS_FRAME as u32, >+ ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 >+ | ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 >+ | NODE_DESCENDANTS_NEED_FRAMES as u32 >+ | NODE_NEEDS_FRAME as u32, > ) > } > > fn is_visited_link(&self) -> bool { > self.state().intersects(ElementState::IN_VISITED_STATE) > } > > /// This logic is duplicated in Gecko's nsINode::IsInNativeAnonymousSubtree. >@@ -1434,18 +1438,20 @@ impl<'le> TElement for GeckoElement<'le> { > self.0.mServoData.set(ptr); > } > self.mutate_data().unwrap() > } > > unsafe fn clear_data(&self) { > let ptr = self.0.mServoData.get(); > self.unset_flags( >- ELEMENT_HAS_SNAPSHOT as u32 | ELEMENT_HANDLED_SNAPSHOT as u32 | >- structs::Element_kAllServoDescendantBits | NODE_NEEDS_FRAME as u32, >+ ELEMENT_HAS_SNAPSHOT as u32 >+ | ELEMENT_HANDLED_SNAPSHOT as u32 >+ | structs::Element_kAllServoDescendantBits >+ | NODE_NEEDS_FRAME as u32, > ); > if !ptr.is_null() { > debug!("Dropping ElementData for {:?}", self); > let data = Box::from_raw(self.0.mServoData.get()); > self.0.mServoData.set(ptr::null_mut()); > > // Perform a mutable borrow of the data in debug builds. This > // serves as an assertion that there are no outstanding borrows >@@ -1645,60 +1651,58 @@ impl<'le> TElement for GeckoElement<'le> { > ); > > let after_change_box_style = after_change_style.get_box(); > let transitions_count = after_change_box_style.transition_property_count(); > let existing_transitions = self.css_transitions_info(); > > // Check if this property is none, custom or unknown. > let is_none_or_custom_property = |property: nsCSSPropertyID| -> bool { >- return property == nsCSSPropertyID::eCSSPropertyExtra_no_properties || >- property == nsCSSPropertyID::eCSSPropertyExtra_variable || >- property == nsCSSPropertyID::eCSSProperty_UNKNOWN; >+ return property == nsCSSPropertyID::eCSSPropertyExtra_no_properties >+ || property == nsCSSPropertyID::eCSSPropertyExtra_variable >+ || property == nsCSSPropertyID::eCSSProperty_UNKNOWN; > }; > > let mut transitions_to_keep = LonghandIdSet::new(); > > for i in 0..transitions_count { > let property = after_change_box_style.transition_nscsspropertyid_at(i); > let combined_duration = after_change_box_style.transition_combined_duration_at(i); > > // We don't need to update transition for none/custom properties. > if is_none_or_custom_property(property) { > continue; > } > > let transition_property: TransitionProperty = property.into(); > > let mut property_check_helper = |property: LonghandId| -> bool { >- let property = >- property.to_physical(after_change_style.writing_mode); >+ let property = property.to_physical(after_change_style.writing_mode); > transitions_to_keep.insert(property); > self.needs_transitions_update_per_property( > property, > combined_duration, > before_change_style, > after_change_style, > &existing_transitions, > ) > }; > > match transition_property { >- TransitionProperty::Custom(..) | >- TransitionProperty::Unsupported(..) => {}, >+ TransitionProperty::Custom(..) | TransitionProperty::Unsupported(..) => {} > TransitionProperty::Shorthand(ref shorthand) => { > if shorthand.longhands().any(property_check_helper) { > return true; > } >- }, >+ } > TransitionProperty::Longhand(longhand_id) => { > if property_check_helper(longhand_id) { > return true; > } >- }, >+ } > } > } > > // Check if we have to cancel the running transition because this is not > // a matching transition-property value. > existing_transitions > .keys() > .any(|property| !transitions_to_keep.contains(*property)) >@@ -1803,18 +1807,18 @@ impl<'le> TElement for GeckoElement<'le> { > }; > }; > > let ns = self.namespace_id(); > // <th> elements get a default MozCenterOrInherit which may get overridden > if ns == structs::kNameSpaceID_XHTML as i32 { > if self.local_name().as_ptr() == atom!("th").as_ptr() { > hints.push(TH_RULE.clone()); >- } else if self.local_name().as_ptr() == atom!("table").as_ptr() && >- self.as_node().owner_doc().quirks_mode() == QuirksMode::Quirks >+ } else if self.local_name().as_ptr() == atom!("table").as_ptr() >+ && self.as_node().owner_doc().quirks_mode() == QuirksMode::Quirks > { > hints.push(TABLE_COLOR_RULE.clone()); > } > } > if ns == structs::kNameSpaceID_SVG as i32 { > if self.local_name().as_ptr() == atom!("text").as_ptr() { > hints.push(SVG_TEXT_DISABLE_ZOOM_RULE.clone()); > } >@@ -1843,34 +1847,35 @@ impl<'le> TElement for GeckoElement<'le> { > // Unvisited vs. visited styles are computed up-front based on the > // visited mode (not the element's actual state). > let declarations = match visited_handling { > VisitedHandlingMode::AllLinksVisitedAndUnvisited => { > unreachable!( > "We should never try to selector match with \ > AllLinksVisitedAndUnvisited" > ); >- }, >+ } > VisitedHandlingMode::AllLinksUnvisited => unsafe { > Gecko_GetUnvisitedLinkAttrDeclarationBlock(self.0) > }, > VisitedHandlingMode::RelevantLinkVisited => unsafe { > Gecko_GetVisitedLinkAttrDeclarationBlock(self.0) > }, > }; > let declarations: Option<&RawOffsetArc<Locked<PropertyDeclarationBlock>>> = > declarations.and_then(|s| s.as_arc_opt()); > if let Some(decl) = declarations { > hints.push(ApplicableDeclarationBlock::from_declarations( > decl.clone_arc(), > ServoCascadeLevel::PresHints, > )); > } > >- let active = self.state() >+ let active = self >+ .state() > .intersects(NonTSPseudoClass::Active.state_flag()); > if active { > let declarations = unsafe { Gecko_GetActiveLinkAttrDeclarationBlock(self.0) }; > let declarations: Option< > &RawOffsetArc<Locked<PropertyDeclarationBlock>>, > > = declarations.and_then(|s| s.as_arc_opt()); > if let Some(decl) = declarations { > hints.push(ApplicableDeclarationBlock::from_declarations( >@@ -2008,17 +2013,17 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { > ns: &NamespaceConstraint<&Namespace>, > local_name: &Atom, > operation: &AttrSelectorOperation<&Atom>, > ) -> bool { > unsafe { > match *operation { > AttrSelectorOperation::Exists => { > bindings::Gecko_HasAttr(self.0, ns.atom_or_null(), local_name.as_ptr()) >- }, >+ } > AttrSelectorOperation::WithValue { > operator, > case_sensitivity, > expected_value, > } => { > let ignore_case = match case_sensitivity { > CaseSensitivity::CaseSensitive => false, > CaseSensitivity::AsciiCaseInsensitive => true, >@@ -2063,37 +2068,45 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { > AttrSelectorOperator::Substring => bindings::Gecko_AttrHasSubstring( > self.0, > ns.atom_or_null(), > local_name.as_ptr(), > expected_value.as_ptr(), > ignore_case, > ), > } >- }, >+ } > } > } > } > > #[inline] > fn is_root(&self) -> bool { >- if self.as_node().get_bool_flag(nsINode_BooleanFlag::ParentIsContent) { >+ if self >+ .as_node() >+ .get_bool_flag(nsINode_BooleanFlag::ParentIsContent) >+ { > return false; > } > > if !self.as_node().is_in_document() { > return false; > } > >- debug_assert!(self.as_node().parent_node().map_or(false, |p| p.is_document())); >+ debug_assert!( >+ self.as_node() >+ .parent_node() >+ .map_or(false, |p| p.is_document()) >+ ); > unsafe { bindings::Gecko_IsRootElement(self.0) } > } > > fn is_empty(&self) -> bool { >- !self.as_node() >+ !self >+ .as_node() > .dom_children() > .any(|child| unsafe { Gecko_IsSignificantChild(child.0, true) }) > } > > #[inline] > fn local_name(&self) -> &WeakAtom { > unsafe { WeakAtom::new(self.as_node().node_info().mInner.mName) } > } >@@ -2112,128 +2125,129 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { > context: &mut MatchingContext<Self::Impl>, > flags_setter: &mut F, > ) -> bool > where > F: FnMut(&Self, ElementSelectorFlags), > { > use selectors::matching::*; > match *pseudo_class { >- NonTSPseudoClass::Defined | >- NonTSPseudoClass::Focus | >- NonTSPseudoClass::Enabled | >- NonTSPseudoClass::Disabled | >- NonTSPseudoClass::Checked | >- NonTSPseudoClass::Fullscreen | >- NonTSPseudoClass::MozFullScreen | >- NonTSPseudoClass::Indeterminate | >- NonTSPseudoClass::PlaceholderShown | >- NonTSPseudoClass::Target | >- NonTSPseudoClass::Valid | >- NonTSPseudoClass::Invalid | >- NonTSPseudoClass::MozUIValid | >- NonTSPseudoClass::MozBroken | >- NonTSPseudoClass::MozUserDisabled | >- NonTSPseudoClass::MozSuppressed | >- NonTSPseudoClass::MozLoading | >- NonTSPseudoClass::MozHandlerBlocked | >- NonTSPseudoClass::MozHandlerDisabled | >- NonTSPseudoClass::MozHandlerCrashed | >- NonTSPseudoClass::Required | >- NonTSPseudoClass::Optional | >- NonTSPseudoClass::MozReadOnly | >- NonTSPseudoClass::MozReadWrite | >- NonTSPseudoClass::FocusWithin | >- NonTSPseudoClass::MozDragOver | >- NonTSPseudoClass::MozDevtoolsHighlighted | >- NonTSPseudoClass::MozStyleeditorTransitioning | >- NonTSPseudoClass::MozFocusRing | >- NonTSPseudoClass::MozHandlerClickToPlay | >- NonTSPseudoClass::MozHandlerVulnerableUpdatable | >- NonTSPseudoClass::MozHandlerVulnerableNoUpdate | >- NonTSPseudoClass::MozMathIncrementScriptLevel | >- NonTSPseudoClass::InRange | >- NonTSPseudoClass::OutOfRange | >- NonTSPseudoClass::Default | >- NonTSPseudoClass::MozSubmitInvalid | >- NonTSPseudoClass::MozUIInvalid | >- NonTSPseudoClass::MozMeterOptimum | >- NonTSPseudoClass::MozMeterSubOptimum | >- NonTSPseudoClass::MozMeterSubSubOptimum | >- NonTSPseudoClass::MozHasDirAttr | >- NonTSPseudoClass::MozDirAttrLTR | >- NonTSPseudoClass::MozDirAttrRTL | >- NonTSPseudoClass::MozDirAttrLikeAuto | >- NonTSPseudoClass::MozAutofill | >- NonTSPseudoClass::Active | >- NonTSPseudoClass::Hover | >- NonTSPseudoClass::MozAutofillPreview => { >+ NonTSPseudoClass::Defined >+ | NonTSPseudoClass::Focus >+ | NonTSPseudoClass::Enabled >+ | NonTSPseudoClass::Disabled >+ | NonTSPseudoClass::Checked >+ | NonTSPseudoClass::Fullscreen >+ | NonTSPseudoClass::MozFullScreen >+ | NonTSPseudoClass::Indeterminate >+ | NonTSPseudoClass::PlaceholderShown >+ | NonTSPseudoClass::Target >+ | NonTSPseudoClass::Valid >+ | NonTSPseudoClass::Invalid >+ | NonTSPseudoClass::MozUIValid >+ | NonTSPseudoClass::MozBroken >+ | NonTSPseudoClass::MozUserDisabled >+ | NonTSPseudoClass::MozSuppressed >+ | NonTSPseudoClass::MozLoading >+ | NonTSPseudoClass::MozHandlerBlocked >+ | NonTSPseudoClass::MozHandlerDisabled >+ | NonTSPseudoClass::MozHandlerCrashed >+ | NonTSPseudoClass::Required >+ | NonTSPseudoClass::Optional >+ | NonTSPseudoClass::MozReadOnly >+ | NonTSPseudoClass::MozReadWrite >+ | NonTSPseudoClass::FocusWithin >+ | NonTSPseudoClass::MozDragOver >+ | NonTSPseudoClass::MozDevtoolsHighlighted >+ | NonTSPseudoClass::MozStyleeditorTransitioning >+ | NonTSPseudoClass::MozFocusRing >+ | NonTSPseudoClass::MozHandlerClickToPlay >+ | NonTSPseudoClass::MozHandlerVulnerableUpdatable >+ | NonTSPseudoClass::MozHandlerVulnerableNoUpdate >+ | NonTSPseudoClass::MozMathIncrementScriptLevel >+ | NonTSPseudoClass::InRange >+ | NonTSPseudoClass::OutOfRange >+ | NonTSPseudoClass::Default >+ | NonTSPseudoClass::MozSubmitInvalid >+ | NonTSPseudoClass::MozUIInvalid >+ | NonTSPseudoClass::MozMeterOptimum >+ | NonTSPseudoClass::MozMeterSubOptimum >+ | NonTSPseudoClass::MozMeterSubSubOptimum >+ | NonTSPseudoClass::MozHasDirAttr >+ | NonTSPseudoClass::MozDirAttrLTR >+ | NonTSPseudoClass::MozDirAttrRTL >+ | NonTSPseudoClass::MozDirAttrLikeAuto >+ | NonTSPseudoClass::MozAutofill >+ | NonTSPseudoClass::Active >+ | NonTSPseudoClass::Hover >+ | NonTSPseudoClass::MozAutofillPreview => { > self.state().intersects(pseudo_class.state_flag()) >- }, >+ } > NonTSPseudoClass::AnyLink => self.is_link(), > NonTSPseudoClass::Link => { > self.is_link() && context.visited_handling().matches_unvisited() >- }, >+ } > NonTSPseudoClass::Visited => { > self.is_link() && context.visited_handling().matches_visited() >- }, >+ } > NonTSPseudoClass::MozFirstNode => { > flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); > let mut elem = self.as_node(); > while let Some(prev) = elem.prev_sibling() { > if prev.contains_non_whitespace_content() { > return false; > } > elem = prev; > } > true >- }, >+ } > NonTSPseudoClass::MozLastNode => { > flags_setter(self, ElementSelectorFlags::HAS_EDGE_CHILD_SELECTOR); > let mut elem = self.as_node(); > while let Some(next) = elem.next_sibling() { > if next.contains_non_whitespace_content() { > return false; > } > elem = next; > } > true >- }, >+ } > NonTSPseudoClass::MozOnlyWhitespace => { > flags_setter(self, ElementSelectorFlags::HAS_EMPTY_SELECTOR); >- if self.as_node() >+ if self >+ .as_node() > .dom_children() > .any(|c| c.contains_non_whitespace_content()) > { > return false; > } > true >- }, >+ } > NonTSPseudoClass::MozNativeAnonymous => self.is_in_native_anonymous_subtree(), > NonTSPseudoClass::MozUseShadowTreeRoot => self.is_root_of_use_element_shadow_tree(), > NonTSPseudoClass::MozTableBorderNonzero => unsafe { > bindings::Gecko_IsTableBorderNonzero(self.0) > }, > NonTSPseudoClass::MozBrowserFrame => unsafe { bindings::Gecko_IsBrowserFrame(self.0) }, > NonTSPseudoClass::MozIsHTML => self.is_html_element_in_html_document(), > NonTSPseudoClass::MozLWTheme => self.document_theme() != DocumentTheme::Doc_Theme_None, > NonTSPseudoClass::MozLWThemeBrightText => { > self.document_theme() == DocumentTheme::Doc_Theme_Bright >- }, >+ } > NonTSPseudoClass::MozLWThemeDarkText => { > self.document_theme() == DocumentTheme::Doc_Theme_Dark >- }, >+ } > NonTSPseudoClass::MozWindowInactive => { > let state_bit = DocumentState::NS_DOCUMENT_STATE_WINDOW_INACTIVE; > if context.extra_data.document_state.intersects(state_bit) { > return !context.in_negation(); > } > > self.document_state().contains(state_bit) >- }, >+ } > NonTSPseudoClass::MozPlaceholder => false, > NonTSPseudoClass::MozAny(ref sels) => context.nest(|context| { > sels.iter() > .any(|s| matches_complex_selector(s.iter(), self, context, flags_setter)) > }), > NonTSPseudoClass::Lang(ref lang_arg) => self.match_element_lang(None, lang_arg), > NonTSPseudoClass::MozLocaleDir(ref dir) => { > let state_bit = DocumentState::NS_DOCUMENT_STATE_RTL_LOCALE; >@@ -2245,17 +2259,17 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { > > let doc_is_rtl = self.document_state().contains(state_bit); > > match **dir { > Direction::Ltr => !doc_is_rtl, > Direction::Rtl => doc_is_rtl, > Direction::Other(..) => false, > } >- }, >+ } > NonTSPseudoClass::Dir(ref dir) => match **dir { > Direction::Ltr => self.state().intersects(ElementState::IN_LTR_STATE), > Direction::Rtl => self.state().intersects(ElementState::IN_RTL_STATE), > Direction::Other(..) => false, > }, > } > } > >diff --git a/servo/components/style/gecko_bindings/mod.rs b/servo/components/style/gecko_bindings/mod.rs >index eb3f0d220bf5..166e2f66fd56 100644 >--- a/servo/components/style/gecko_bindings/mod.rs >+++ b/servo/components/style/gecko_bindings/mod.rs >@@ -1,22 +1,33 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Gecko's C++ bindings, along with some rust helpers to ease its use. > >-#[allow(dead_code, improper_ctypes, non_camel_case_types, missing_docs)] >+#[allow( >+ dead_code, >+ improper_ctypes, >+ non_camel_case_types, >+ missing_docs >+)] > pub mod bindings { > include!(concat!(env!("OUT_DIR"), "/gecko/bindings.rs")); > } > > // FIXME: We allow `improper_ctypes` (for now), because the lint doesn't allow > // foreign structs to have `PhantomData`. We should remove this once the lint > // ignores this case. > >-#[allow(dead_code, improper_ctypes, non_camel_case_types, non_snake_case, non_upper_case_globals, >- missing_docs)] >+#[allow( >+ dead_code, >+ improper_ctypes, >+ non_camel_case_types, >+ non_snake_case, >+ non_upper_case_globals, >+ missing_docs >+)] > pub mod structs { > include!(concat!(env!("OUT_DIR"), "/gecko/structs.rs")); > } > > pub mod sugar; >diff --git a/servo/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs b/servo/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs >index 8e445a837e62..f0050796c22c 100644 >--- a/servo/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs >+++ b/servo/components/style/gecko_bindings/sugar/ns_css_shadow_array.rs >@@ -2,19 +2,19 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Rust helpers for Gecko's `nsCSSShadowArray`. > > use gecko_bindings::bindings::Gecko_AddRefCSSShadowArrayArbitraryThread; > use gecko_bindings::bindings::Gecko_NewCSSShadowArray; > use gecko_bindings::bindings::Gecko_ReleaseCSSShadowArrayArbitraryThread; >-use gecko_bindings::structs::{RefPtr, nsCSSShadowArray, nsCSSShadowItem}; >-use std::{ptr, slice}; >+use gecko_bindings::structs::{nsCSSShadowArray, nsCSSShadowItem, RefPtr}; > use std::ops::{Deref, DerefMut}; >+use std::{ptr, slice}; > > impl RefPtr<nsCSSShadowArray> { > /// Replaces the current `nsCSSShadowArray` with a new one of len `len`. > pub fn replace_with_new(&mut self, len: u32) { > unsafe { > if !self.mRawPtr.is_null() { > Gecko_ReleaseCSSShadowArrayArbitraryThread(self.mRawPtr); > } >diff --git a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs >index 644166e3797e..b160041500e1 100644 >--- a/servo/components/style/gecko_bindings/sugar/ns_css_value.rs >+++ b/servo/components/style/gecko_bindings/sugar/ns_css_value.rs >@@ -28,18 +28,18 @@ impl nsCSSValue { > pub fn is_none(&self) -> bool { > self.mUnit == nsCSSUnit::eCSSUnit_None > } > > /// Returns this nsCSSValue value as an integer, unchecked in release > /// builds. > pub fn integer_unchecked(&self) -> i32 { > debug_assert!( >- self.mUnit == nsCSSUnit::eCSSUnit_Integer || >- self.mUnit == nsCSSUnit::eCSSUnit_Enumerated >+ self.mUnit == nsCSSUnit::eCSSUnit_Integer >+ || self.mUnit == nsCSSUnit::eCSSUnit_Enumerated > ); > unsafe { *self.mValue.mInt.as_ref() } > } > > /// Checks if it is an integer and returns it if so > pub fn integer(&self) -> Option<i32> { > if self.mUnit == nsCSSUnit::eCSSUnit_Integer || self.mUnit == nsCSSUnit::eCSSUnit_Enumerated > { >@@ -55,18 +55,18 @@ impl nsCSSValue { > debug_assert!(nsCSSUnit::eCSSUnit_Number as u32 <= self.mUnit as u32); > unsafe { *self.mValue.mFloat.as_ref() } > } > > /// Returns this nsCSSValue as a nsCSSValue::Array, unchecked in release > /// builds. > pub unsafe fn array_unchecked(&self) -> &nsCSSValue_Array { > debug_assert!( >- nsCSSUnit::eCSSUnit_Array as u32 <= self.mUnit as u32 && >- self.mUnit as u32 <= nsCSSUnit::eCSSUnit_Calc_Divided as u32 >+ nsCSSUnit::eCSSUnit_Array as u32 <= self.mUnit as u32 >+ && self.mUnit as u32 <= nsCSSUnit::eCSSUnit_Calc_Divided as u32 > ); > let array = *self.mValue.mArray.as_ref(); > debug_assert!(!array.is_null()); > &*array > } > > /// Sets LengthOrPercentage value to this nsCSSValue. > pub unsafe fn set_lop(&mut self, lop: LengthOrPercentage) { >@@ -87,23 +87,23 @@ impl nsCSSValue { > bindings::Gecko_CSSValue_SetPercentage(self, unit_value) > } > > /// Returns LengthOrPercentage value. > pub unsafe fn get_lop(&self) -> LengthOrPercentage { > match self.mUnit { > nsCSSUnit::eCSSUnit_Pixel => { > LengthOrPercentage::Length(Length::new(bindings::Gecko_CSSValue_GetNumber(self))) >- }, >+ } > nsCSSUnit::eCSSUnit_Percent => LengthOrPercentage::Percentage(Percentage( > bindings::Gecko_CSSValue_GetPercentage(self), > )), > nsCSSUnit::eCSSUnit_Calc => { > LengthOrPercentage::Calc(bindings::Gecko_CSSValue_GetCalc(self).into()) >- }, >+ } > _ => panic!("Unexpected unit"), > } > } > > /// Returns Length value. > pub unsafe fn get_length(&self) -> Length { > match self.mUnit { > nsCSSUnit::eCSSUnit_Pixel => Length::new(bindings::Gecko_CSSValue_GetNumber(self)), >@@ -336,17 +336,17 @@ pub struct nsCSSValueListIterator<'a> { > > impl<'a> Iterator for nsCSSValueListIterator<'a> { > type Item = &'a nsCSSValue; > fn next(&mut self) -> Option<Self::Item> { > match self.current { > Some(item) => { > self.current = unsafe { item.mNext.as_ref() }; > Some(&item.mValue) >- }, >+ } > None => None, > } > } > } > > impl<'a> IntoIterator for &'a nsCSSValueList { > type Item = &'a nsCSSValue; > type IntoIter = nsCSSValueListIterator<'a>; >@@ -367,17 +367,17 @@ pub struct nsCSSValueListMutIterator<'a> { > > impl<'a> Iterator for nsCSSValueListMutIterator<'a> { > type Item = &'a mut nsCSSValue; > fn next(&mut self) -> Option<Self::Item> { > match unsafe { self.current.as_mut() } { > Some(item) => { > self.current = item.mNext; > Some(&mut item.mValue) >- }, >+ } > None => None, > } > } > } > > impl<'a> IntoIterator for &'a mut nsCSSValueList { > type Item = &'a mut nsCSSValue; > type IntoIter = nsCSSValueListMutIterator<'a>; >diff --git a/servo/components/style/gecko_bindings/sugar/ns_style_auto_array.rs b/servo/components/style/gecko_bindings/sugar/ns_style_auto_array.rs >index 8adb8bb54d17..256199df7276 100644 >--- a/servo/components/style/gecko_bindings/sugar/ns_style_auto_array.rs >+++ b/servo/components/style/gecko_bindings/sugar/ns_style_auto_array.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Rust helpers for Gecko's `nsStyleAutoArray`. > > use gecko_bindings::bindings::Gecko_EnsureStyleAnimationArrayLength; > use gecko_bindings::bindings::Gecko_EnsureStyleTransitionArrayLength; >-use gecko_bindings::structs::{StyleAnimation, StyleTransition}; > use gecko_bindings::structs::nsStyleAutoArray; >+use gecko_bindings::structs::{StyleAnimation, StyleTransition}; > use std::iter::{once, Chain, IntoIterator, Once}; > use std::ops::{Index, IndexMut}; > use std::slice::{Iter, IterMut}; > > impl<T> Index<usize> for nsStyleAutoArray<T> { > type Output = T; > fn index(&self, index: usize) -> &T { > match index { >diff --git a/servo/components/style/gecko_bindings/sugar/ns_style_coord.rs b/servo/components/style/gecko_bindings/sugar/ns_style_coord.rs >index 3825c5520ecc..d5a327c6e56f 100644 >--- a/servo/components/style/gecko_bindings/sugar/ns_style_coord.rs >+++ b/servo/components/style/gecko_bindings/sugar/ns_style_coord.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Rust helpers for Gecko's `nsStyleCoord`. > > use gecko_bindings::bindings; > use gecko_bindings::structs::{nsStyleCoord, nsStyleCoord_Calc, nsStyleCoord_CalcValue}; >-use gecko_bindings::structs::{nscoord, nsStyleCorners, nsStyleSides, nsStyleUnion, nsStyleUnit}; >+use gecko_bindings::structs::{nsStyleCorners, nsStyleSides, nsStyleUnion, nsStyleUnit, nscoord}; > use std::mem; > > impl nsStyleCoord { > #[inline] > /// Get a `null` nsStyleCoord. > pub fn null() -> Self { > // Can't construct directly because it has private fields > let mut coord: Self = unsafe { mem::zeroed() }; >@@ -47,18 +47,19 @@ impl nsStyleCoord_CalcValue { > mPercent: 0.0, > mHasPercent: false, > } > } > } > > impl PartialEq for nsStyleCoord_CalcValue { > fn eq(&self, other: &Self) -> bool { >- self.mLength == other.mLength && self.mPercent == other.mPercent && >- self.mHasPercent == other.mHasPercent >+ self.mLength == other.mLength >+ && self.mPercent == other.mPercent >+ && self.mHasPercent == other.mHasPercent > } > } > > impl nsStyleSides { > /// Immutably get the `nsStyleCoord`-like object representing the side at > /// index `index`. > #[inline] > pub fn data_at(&self, index: usize) -> SidesData { >@@ -277,82 +278,82 @@ pub unsafe trait CoordDataMut: CoordData { > *unit = eStyleUnit_Null; > *union.mInt.as_mut() = 0; > } > } > > #[inline(always)] > /// Sets the inner value. > fn set_value(&mut self, value: CoordDataValue) { >- use gecko_bindings::structs::nsStyleUnit::*; > use self::CoordDataValue::*; >+ use gecko_bindings::structs::nsStyleUnit::*; > self.reset(); > unsafe { > let (unit, union) = self.values_mut(); > match value { > Null => { > *unit = eStyleUnit_Null; > *union.mInt.as_mut() = 0; >- }, >+ } > Normal => { > *unit = eStyleUnit_Normal; > *union.mInt.as_mut() = 0; >- }, >+ } > Auto => { > *unit = eStyleUnit_Auto; > *union.mInt.as_mut() = 0; >- }, >+ } > None => { > *unit = eStyleUnit_None; > *union.mInt.as_mut() = 0; >- }, >+ } > Percent(f) => { > *unit = eStyleUnit_Percent; > *union.mFloat.as_mut() = f; >- }, >+ } > Factor(f) => { > *unit = eStyleUnit_Factor; > *union.mFloat.as_mut() = f; >- }, >+ } > Degree(f) => { > *unit = eStyleUnit_Degree; > *union.mFloat.as_mut() = f; >- }, >+ } > Grad(f) => { > *unit = eStyleUnit_Grad; > *union.mFloat.as_mut() = f; >- }, >+ } > Radian(f) => { > *unit = eStyleUnit_Radian; > *union.mFloat.as_mut() = f; >- }, >+ } > Turn(f) => { > *unit = eStyleUnit_Turn; > *union.mFloat.as_mut() = f; >- }, >+ } > FlexFraction(f) => { > *unit = eStyleUnit_FlexFraction; > *union.mFloat.as_mut() = f; >- }, >+ } > Coord(coord) => { > *unit = eStyleUnit_Coord; > *union.mInt.as_mut() = coord; >- }, >+ } > Integer(i) => { > *unit = eStyleUnit_Integer; > *union.mInt.as_mut() = i; >- }, >+ } > Enumerated(i) => { > *unit = eStyleUnit_Enumerated; > *union.mInt.as_mut() = i as i32; >- }, >+ } > Calc(calc) => { > // Gecko_SetStyleCoordCalcValue changes the unit internally > bindings::Gecko_SetStyleCoordCalcValue(unit, union, calc); >- }, >+ } > } > } > } > > #[inline] > /// Gets the `Calc` value mutably, asserts in debug builds if the unit is > /// not `Calc`. > unsafe fn as_calc_mut(&mut self) -> &mut nsStyleCoord_Calc { >@@ -376,18 +377,18 @@ pub unsafe trait CoordData { > /// Get the unit of this object. > fn unit(&self) -> nsStyleUnit; > /// Get the `nsStyleUnion` for this object. > fn union(&self) -> nsStyleUnion; > > #[inline(always)] > /// Get the appropriate value for this object. > fn as_value(&self) -> CoordDataValue { >- use gecko_bindings::structs::nsStyleUnit::*; > use self::CoordDataValue::*; >+ use gecko_bindings::structs::nsStyleUnit::*; > unsafe { > match self.unit() { > eStyleUnit_Null => Null, > eStyleUnit_Normal => Normal, > eStyleUnit_Auto => Auto, > eStyleUnit_None => None, > eStyleUnit_Percent => Percent(self.get_float()), > eStyleUnit_Factor => Factor(self.get_float()), >@@ -404,31 +405,35 @@ pub unsafe trait CoordData { > } > } > > #[inline] > /// Pretend inner value is a float; obtain it. > unsafe fn get_float(&self) -> f32 { > use gecko_bindings::structs::nsStyleUnit::*; > debug_assert!( >- self.unit() == eStyleUnit_Percent || self.unit() == eStyleUnit_Factor || >- self.unit() == eStyleUnit_Degree || self.unit() == eStyleUnit_Grad || >- self.unit() == eStyleUnit_Radian || self.unit() == eStyleUnit_Turn || >- self.unit() == eStyleUnit_FlexFraction >+ self.unit() == eStyleUnit_Percent >+ || self.unit() == eStyleUnit_Factor >+ || self.unit() == eStyleUnit_Degree >+ || self.unit() == eStyleUnit_Grad >+ || self.unit() == eStyleUnit_Radian >+ || self.unit() == eStyleUnit_Turn >+ || self.unit() == eStyleUnit_FlexFraction > ); > *self.union().mFloat.as_ref() > } > > #[inline] > /// Pretend inner value is an int; obtain it. > unsafe fn get_integer(&self) -> i32 { > use gecko_bindings::structs::nsStyleUnit::*; > debug_assert!( >- self.unit() == eStyleUnit_Coord || self.unit() == eStyleUnit_Integer || >- self.unit() == eStyleUnit_Enumerated >+ self.unit() == eStyleUnit_Coord >+ || self.unit() == eStyleUnit_Integer >+ || self.unit() == eStyleUnit_Enumerated > ); > *self.union().mInt.as_ref() > } > > #[inline] > /// Pretend inner value is a calc; obtain it. > /// Ensure that the unit is Calc before calling this. > unsafe fn get_calc_value(&self) -> nsStyleCoord_CalcValue { >diff --git a/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs b/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs >index 635b1f867680..b18b25b03b60 100644 >--- a/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs >+++ b/servo/components/style/gecko_bindings/sugar/ns_timing_function.rs >@@ -1,25 +1,25 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > use gecko_bindings::structs::{nsTimingFunction, nsTimingFunction_Type}; > use std::mem; >-use values::computed::ToComputedValue; > use values::computed::transform::TimingFunction as ComputedTimingFunction; >-use values::generics::transform::{StepPosition, TimingKeyword}; >+use values::computed::ToComputedValue; > use values::generics::transform::TimingFunction as GenericTimingFunction; >+use values::generics::transform::{StepPosition, TimingKeyword}; > use values::specified::transform::TimingFunction; > > impl nsTimingFunction { > fn set_as_step(&mut self, function_type: nsTimingFunction_Type, steps: u32) { > debug_assert!( >- function_type == nsTimingFunction_Type::StepStart || >- function_type == nsTimingFunction_Type::StepEnd, >+ function_type == nsTimingFunction_Type::StepStart >+ || function_type == nsTimingFunction_Type::StepEnd, > "function_type should be step-start or step-end" > ); > self.mType = function_type; > unsafe { > self.__bindgen_anon_1 > .__bindgen_anon_1 > .as_mut() > .mStepsOrFrames = steps; >@@ -64,38 +64,38 @@ impl From<ComputedTimingFunction> for nsTimingFunction { > impl From<TimingFunction> for nsTimingFunction { > fn from(function: TimingFunction) -> nsTimingFunction { > let mut tf: nsTimingFunction = unsafe { mem::zeroed() }; > > match function { > GenericTimingFunction::Steps(steps, StepPosition::Start) => { > debug_assert!(steps.value() >= 0); > tf.set_as_step(nsTimingFunction_Type::StepStart, steps.value() as u32); >- }, >+ } > GenericTimingFunction::Steps(steps, StepPosition::End) => { > debug_assert!(steps.value() >= 0); > tf.set_as_step(nsTimingFunction_Type::StepEnd, steps.value() as u32); >- }, >+ } > GenericTimingFunction::Frames(frames) => { > debug_assert!(frames.value() >= 2); > tf.set_as_frames(frames.value() as u32); >- }, >+ } > GenericTimingFunction::CubicBezier { x1, y1, x2, y2 } => { > tf.set_as_bezier( > nsTimingFunction_Type::CubicBezier, > x1.get(), > y1.get(), > x2.get(), > y2.get(), > ); >- }, >+ } > GenericTimingFunction::Keyword(keyword) => { > let (x1, y1, x2, y2) = keyword.to_bezier(); > tf.set_as_bezier(keyword.into(), x1, y1, x2, y2); >- }, >+ } > } > tf > } > } > > impl From<nsTimingFunction> for ComputedTimingFunction { > fn from(function: nsTimingFunction) -> ComputedTimingFunction { > match function.mType { >@@ -126,20 +126,20 @@ impl From<nsTimingFunction> for ComputedTimingFunction { > .as_ref() > .mStepsOrFrames > }), > nsTimingFunction_Type::Ease => GenericTimingFunction::Keyword(TimingKeyword::Ease), > nsTimingFunction_Type::Linear => GenericTimingFunction::Keyword(TimingKeyword::Linear), > nsTimingFunction_Type::EaseIn => GenericTimingFunction::Keyword(TimingKeyword::EaseIn), > nsTimingFunction_Type::EaseOut => { > GenericTimingFunction::Keyword(TimingKeyword::EaseOut) >- }, >+ } > nsTimingFunction_Type::EaseInOut => { > GenericTimingFunction::Keyword(TimingKeyword::EaseInOut) >- }, >+ } > nsTimingFunction_Type::CubicBezier => unsafe { > GenericTimingFunction::CubicBezier { > x1: function.__bindgen_anon_1.mFunc.as_ref().mX1, > y1: function.__bindgen_anon_1.mFunc.as_ref().mY1, > x2: function.__bindgen_anon_1.mFunc.as_ref().mX2, > y2: function.__bindgen_anon_1.mFunc.as_ref().mY2, > } > }, >diff --git a/servo/components/style/gecko_bindings/sugar/refptr.rs b/servo/components/style/gecko_bindings/sugar/refptr.rs >index 6a32b81430e1..5351702f2e47 100644 >--- a/servo/components/style/gecko_bindings/sugar/refptr.rs >+++ b/servo/components/style/gecko_bindings/sugar/refptr.rs >@@ -1,21 +1,21 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A rust helper to ease the use of Gecko's refcounted types. > >-use Atom; >-use gecko_bindings::{structs, bindings}; > use gecko_bindings::sugar::ownership::HasArcFFI; >+use gecko_bindings::{bindings, structs}; > use servo_arc::Arc; >-use std::{fmt, mem, ptr}; > use std::marker::PhantomData; > use std::ops::{Deref, DerefMut}; >+use std::{fmt, mem, ptr}; >+use Atom; > > /// Trait for all objects that have Addref() and Release > /// methods and can be placed inside RefPtr<T> > pub unsafe trait RefCounted { > /// Bump the reference count. > fn addref(&self); > /// Decrease the reference count. > unsafe fn release(&self); >@@ -316,13 +316,9 @@ impl_threadsafe_refcount!( > #[inline] > unsafe fn addref_atom(atom: *mut structs::nsAtom) { > mem::forget(Atom::from_raw(atom)); > } > #[inline] > unsafe fn release_atom(atom: *mut structs::nsAtom) { > let _ = Atom::from_addrefed(atom); > } >-impl_threadsafe_refcount!( >- structs::nsAtom, >- addref_atom, >- release_atom >-); >+impl_threadsafe_refcount!(structs::nsAtom, addref_atom, release_atom); >diff --git a/servo/components/style/gecko_bindings/sugar/style_complex_color.rs b/servo/components/style/gecko_bindings/sugar/style_complex_color.rs >index 90e93b72fd08..feb47f7e53cc 100644 >--- a/servo/components/style/gecko_bindings/sugar/style_complex_color.rs >+++ b/servo/components/style/gecko_bindings/sugar/style_complex_color.rs >@@ -2,20 +2,20 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Rust helpers to interact with Gecko's StyleComplexColor. > > use gecko::values::{convert_nscolor_to_rgba, convert_rgba_to_nscolor}; > use gecko_bindings::structs::StyleComplexColor; > use gecko_bindings::structs::StyleComplexColor_Tag as Tag; >-use values::{Auto, Either}; >-use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA}; > use values::computed::ui::ColorOrAuto; >+use values::computed::{Color as ComputedColor, RGBAColor as ComputedRGBA}; > use values::generics::color::{Color as GenericColor, ComplexColorRatios}; >+use values::{Auto, Either}; > > impl StyleComplexColor { > /// Create a `StyleComplexColor` value that represents `currentColor`. > pub fn current_color() -> Self { > StyleComplexColor { > mColor: 0, > mBgRatio: 0., > mFgRatio: 1., >diff --git a/servo/components/style/gecko_string_cache/mod.rs b/servo/components/style/gecko_string_cache/mod.rs >index 70217f233de9..90855f24407c 100644 >--- a/servo/components/style/gecko_string_cache/mod.rs >+++ b/servo/components/style/gecko_string_cache/mod.rs >@@ -8,23 +8,23 @@ > > use gecko_bindings::bindings::Gecko_AddRefAtom; > use gecko_bindings::bindings::Gecko_Atomize; > use gecko_bindings::bindings::Gecko_Atomize16; > use gecko_bindings::bindings::Gecko_ReleaseAtom; > use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsDynamicAtom, nsStaticAtom}; > use nsstring::{nsAString, nsStr}; > use precomputed_hash::PrecomputedHash; >-use std::{mem, slice, str}; > use std::borrow::{Borrow, Cow}; > use std::char::{self, DecodeUtf16}; > use std::fmt::{self, Write}; > use std::hash::{Hash, Hasher}; > use std::iter::Cloned; > use std::ops::Deref; >+use std::{mem, slice, str}; > use style_traits::SpecifiedValueInfo; > > #[macro_use] > #[allow(improper_ctypes, non_camel_case_types, missing_docs)] > pub mod atom_macro { > include!(concat!(env!("OUT_DIR"), "/gecko/atom_macro.rs")); > } > >@@ -212,17 +212,17 @@ impl WeakAtom { > &mut vec > }; > for char16 in &mut mutable_slice[i..] { > if *char16 <= 0x7F { > *char16 = (*char16 as u8).to_ascii_lowercase() as u16 > } > } > Atom::from(&*mutable_slice) >- }, >+ } > } > } > > /// Return whether two atoms are ASCII-case-insensitive matches > pub fn eq_ignore_ascii_case(&self, other: &Self) -> bool { > if self == other { > return true; > } >diff --git a/servo/components/style/invalidation/element/element_wrapper.rs b/servo/components/style/invalidation/element/element_wrapper.rs >index cb4f79e92e1a..03a3cb92b36d 100644 >--- a/servo/components/style/invalidation/element/element_wrapper.rs >+++ b/servo/components/style/invalidation/element/element_wrapper.rs >@@ -1,25 +1,25 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A wrapper over an element and a snapshot, that allows us to selector-match > //! against a past state of the element. > >-use {Atom, CaseSensitivityExt, LocalName, Namespace, WeakAtom}; > use dom::TElement; > use element_state::ElementState; > use selector_parser::{AttrValue, NonTSPseudoClass, PseudoElement, SelectorImpl}; > use selector_parser::{Snapshot, SnapshotMap}; >-use selectors::{Element, OpaqueElement}; > use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; > use selectors::matching::{ElementSelectorFlags, MatchingContext}; >+use selectors::{Element, OpaqueElement}; > use std::cell::Cell; > use std::fmt; >+use {Atom, CaseSensitivityExt, LocalName, Namespace, WeakAtom}; > > /// In order to compute restyle hints, we perform a selector match against a > /// list of partial selectors whose rightmost simple selector may be sensitive > /// to the thing being changed. We do this matching twice, once for the element > /// as it exists now and once for the element as it existed at the time of the > /// last restyle. If the results of the selector match differ, that means that > /// the given partial selector is sensitive to the change, and we compute a > /// restyle hint based on its combinator. >@@ -41,17 +41,19 @@ pub trait ElementSnapshot: Sized { > fn state(&self) -> Option<ElementState>; > > /// If this snapshot contains attribute information. > fn has_attrs(&self) -> bool; > > /// Gets the attribute information of the snapshot as a string. > /// > /// Only for debugging purposes. >- fn debug_list_attributes(&self) -> String { String::new() } >+ fn debug_list_attributes(&self) -> String { >+ String::new() >+ } > > /// The ID attribute per this snapshot. Should only be called if > /// `has_attrs()` returns true. > fn id_attr(&self) -> Option<&WeakAtom>; > > /// Whether this snapshot contains the class `name`. Should only be called > /// if `has_attrs()` returns true. > fn has_class(&self, name: &Atom, case_sensitivity: CaseSensitivity) -> bool; >@@ -171,17 +173,17 @@ where > #[cfg(feature = "gecko")] > NonTSPseudoClass::MozAny(ref selectors) => { > use selectors::matching::matches_complex_selector; > return context.nest(|context| { > selectors > .iter() > .any(|s| matches_complex_selector(s.iter(), self, context, _setter)) > }); >- }, >+ } > > // :dir is implemented in terms of state flags, but which state flag > // it maps to depends on the argument to :dir. That means we can't > // just add its state flags to the NonTSPseudoClass, because if we > // added all of them there, and tested via intersects() here, we'd > // get incorrect behavior for :not(:dir()) cases. > // > // FIXME(bz): How can I set this up so once Servo adds :dir() >@@ -194,66 +196,69 @@ where > // :dir() with some random argument; does not match. > return false; > } > let state = match self.snapshot().and_then(|s| s.state()) { > Some(snapshot_state) => snapshot_state, > None => self.element.state(), > }; > return state.contains(selector_flag); >- }, >+ } > > // For :link and :visited, we don't actually want to test the > // element state directly. > // > // Instead, we use the `visited_handling` to determine if they > // match. > NonTSPseudoClass::Link => { > return self.is_link() && context.visited_handling().matches_unvisited() >- }, >+ } > NonTSPseudoClass::Visited => { > return self.is_link() && context.visited_handling().matches_visited() >- }, >+ } > > #[cfg(feature = "gecko")] > NonTSPseudoClass::MozTableBorderNonzero => { > if let Some(snapshot) = self.snapshot() { > if snapshot.has_other_pseudo_class_state() { > return snapshot.mIsTableBorderNonzero(); > } > } >- }, >+ } > > #[cfg(feature = "gecko")] > NonTSPseudoClass::MozBrowserFrame => { > if let Some(snapshot) = self.snapshot() { > if snapshot.has_other_pseudo_class_state() { > return snapshot.mIsMozBrowserFrame(); > } > } >- }, >+ } > > // :lang() needs to match using the closest ancestor xml:lang="" or > // lang="" attribtue from snapshots. > NonTSPseudoClass::Lang(ref lang_arg) => { >- return self.element >+ return self >+ .element > .match_element_lang(Some(self.get_lang()), lang_arg); >- }, >+ } > >- _ => {}, >+ _ => {} > } > > let flag = pseudo_class.state_flag(); > if flag.is_empty() { >- return self.element >+ return self >+ .element > .match_non_ts_pseudo_class(pseudo_class, context, &mut |_, _| {}); > } > match self.snapshot().and_then(|s| s.state()) { > Some(snapshot_state) => snapshot_state.intersects(flag), >- None => self.element >+ None => self >+ .element > .match_non_ts_pseudo_class(pseudo_class, context, &mut |_, _| {}), > } > } > > fn match_pseudo_element( > &self, > pseudo_element: &PseudoElement, > context: &mut MatchingContext<Self::Impl>, >@@ -317,17 +322,17 @@ where > &self, > ns: &NamespaceConstraint<&Namespace>, > local_name: &LocalName, > operation: &AttrSelectorOperation<&AttrValue>, > ) -> bool { > match self.snapshot() { > Some(snapshot) if snapshot.has_attrs() => { > snapshot.attr_matches(ns, local_name, operation) >- }, >+ } > _ => self.element.attr_matches(ns, local_name, operation), > } > } > > fn has_id(&self, id: &Atom, case_sensitivity: CaseSensitivity) -> bool { > match self.snapshot() { > Some(snapshot) if snapshot.has_attrs() => snapshot > .id_attr() >diff --git a/servo/components/style/invalidation/element/invalidation_map.rs b/servo/components/style/invalidation/element/invalidation_map.rs >index 67849d896270..bdb6b84521b3 100644 >--- a/servo/components/style/invalidation/element/invalidation_map.rs >+++ b/servo/components/style/invalidation/element/invalidation_map.rs >@@ -1,40 +1,40 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Code for invalidations due to state or attribute changes. > >-use {Atom, LocalName, Namespace}; > use context::QuirksMode; > use element_state::{DocumentState, ElementState}; > use fallible::FallibleVec; > use hashglobe::FailedAllocationError; > use selector_map::{MaybeCaseInsensitiveHashMap, SelectorMap, SelectorMapEntry}; > #[cfg(feature = "gecko")] > use selector_parser::Direction; > use selector_parser::SelectorImpl; > use selectors::attr::NamespaceConstraint; > use selectors::parser::{Combinator, Component}; > use selectors::parser::{Selector, SelectorIter, Visit}; > use selectors::visitor::SelectorVisitor; > use smallvec::SmallVec; >+use {Atom, LocalName, Namespace}; > > #[cfg(feature = "gecko")] > /// Gets the element state relevant to the given `:dir` pseudo-class selector. > pub fn dir_selector_to_state(dir: &Direction) -> ElementState { > match *dir { > Direction::Ltr => ElementState::IN_LTR_STATE, > Direction::Rtl => ElementState::IN_RTL_STATE, > Direction::Other(_) => { > // :dir(something-random) is a valid selector, but shouldn't > // match anything. > ElementState::empty() >- }, >+ } > } > } > > /// Mapping between (partial) CompoundSelectors (and the combinator to their > /// right) and the states and attributes they depend on. > /// > /// In general, for all selectors in all applicable stylesheets of the form: > /// >@@ -49,18 +49,20 @@ pub fn dir_selector_to_state(dir: &Direction) -> ElementState { > /// We generate a Dependency for both |a _ b:X _| and |a _ b:X _ c _ d:Y _|, > /// even though those selectors may not appear on their own in any stylesheet. > /// This allows us to quickly scan through the dependency sites of all style > /// rules and determine the maximum effect that a given state or attribute > /// change may have on the style of elements in the document. > #[derive(Clone, Debug, MallocSizeOf)] > pub struct Dependency { > /// The dependency selector. >- #[cfg_attr(feature = "gecko", >- ignore_malloc_size_of = "CssRules have primary refs, we measure there")] >+ #[cfg_attr( >+ feature = "gecko", >+ ignore_malloc_size_of = "CssRules have primary refs, we measure there" >+ )] > #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] > pub selector: Selector<SelectorImpl>, > > /// The offset into the selector that we should match on. > pub selector_offset: usize, > } > > /// The kind of elements down the tree this dependency may affect. >@@ -99,20 +101,20 @@ impl Dependency { > } > > /// The kind of invalidation that this would generate. > pub fn invalidation_kind(&self) -> DependencyInvalidationKind { > match self.combinator() { > None => DependencyInvalidationKind::Element, > Some(Combinator::Child) | Some(Combinator::Descendant) => { > DependencyInvalidationKind::Descendants >- }, >+ } > Some(Combinator::LaterSibling) | Some(Combinator::NextSibling) => { > DependencyInvalidationKind::Siblings >- }, >+ } > // TODO(emilio): We could look at the selector itself to see if it's > // an eager pseudo, and return only Descendants here if not. > Some(Combinator::PseudoElement) => DependencyInvalidationKind::ElementAndDescendants, > Some(Combinator::SlotAssignment) => DependencyInvalidationKind::SlottedElements, > } > } > } > >@@ -138,18 +140,20 @@ impl SelectorMapEntry for StateDependency { > } > } > > /// The same, but for document state selectors. > #[derive(Clone, Debug, MallocSizeOf)] > pub struct DocumentStateDependency { > /// The selector that is affected. We don't need to track an offset, since > /// when it changes it changes for the whole document anyway. >- #[cfg_attr(feature = "gecko", >- ignore_malloc_size_of = "CssRules have primary refs, we measure there")] >+ #[cfg_attr( >+ feature = "gecko", >+ ignore_malloc_size_of = "CssRules have primary refs, we measure there" >+ )] > #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] > pub selector: Selector<SelectorImpl>, > /// The state this dependency is affected by. > pub state: DocumentState, > } > > /// A map where we store invalidations. > /// >@@ -196,22 +200,25 @@ impl InvalidationMap { > other_attribute_affecting_selectors: SelectorMap::new(), > has_class_attribute_selectors: false, > has_id_attribute_selectors: false, > } > } > > /// Returns the number of dependencies stored in the invalidation map. > pub fn len(&self) -> usize { >- self.state_affecting_selectors.len() + self.document_state_selectors.len() + >- self.other_attribute_affecting_selectors.len() + >- self.id_to_selector >+ self.state_affecting_selectors.len() >+ + self.document_state_selectors.len() >+ + self.other_attribute_affecting_selectors.len() >+ + self >+ .id_to_selector > .iter() >- .fold(0, |accum, (_, ref v)| accum + v.len()) + >- self.class_to_selector >+ .fold(0, |accum, (_, ref v)| accum + v.len()) >+ + self >+ .class_to_selector > .iter() > .fold(0, |accum, (_, ref v)| accum + v.len()) > } > > /// Clears this map, leaving it empty. > pub fn clear(&mut self) { > self.class_to_selector.clear(); > self.id_to_selector.clear(); >@@ -369,30 +376,30 @@ impl<'a> SelectorVisitor for CompoundSelectorDependencyCollector<'a> { > > fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool { > #[cfg(feature = "gecko")] > use selector_parser::NonTSPseudoClass; > > match *s { > Component::ID(ref id) => { > self.ids.push(id.clone()); >- }, >+ } > Component::Class(ref class) => { > self.classes.push(class.clone()); >- }, >+ } > Component::NonTSPseudoClass(ref pc) => { > self.other_attributes |= pc.is_attr_based(); > self.state |= match *pc { > #[cfg(feature = "gecko")] > NonTSPseudoClass::Dir(ref dir) => dir_selector_to_state(dir), > _ => pc.state_flag(), > }; > *self.document_state |= pc.document_state_flag(); >- }, >- _ => {}, >+ } >+ _ => {} > } > > true > } > > fn visit_attribute_selector( > &mut self, > constraint: &NamespaceConstraint<&Namespace>, >diff --git a/servo/components/style/invalidation/element/invalidator.rs b/servo/components/style/invalidation/element/invalidator.rs >index 8d60ade88e26..42035e16a893 100644 >--- a/servo/components/style/invalidation/element/invalidator.rs >+++ b/servo/components/style/invalidation/element/invalidator.rs >@@ -3,18 +3,18 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! The struct that takes care of encapsulating all the logic on where and how > //! element styles need to be invalidated. > > use context::StackLimitChecker; > use dom::{TElement, TNode, TShadowRoot}; > use selector_parser::SelectorImpl; >-use selectors::matching::{CompoundSelectorMatchingResult, MatchingContext}; > use selectors::matching::matches_compound_selector_from; >+use selectors::matching::{CompoundSelectorMatchingResult, MatchingContext}; > use selectors::parser::{Combinator, Component, Selector}; > use smallvec::SmallVec; > use std::fmt; > > /// A trait to abstract the collection of invalidations for a given pass. > pub trait InvalidationProcessor<'a, E> > where > E: TElement, >@@ -165,20 +165,20 @@ impl<'a> Invalidation<'a> { > fn kind(&self) -> InvalidationKind { > if self.offset == 0 { > return InvalidationKind::Descendant(DescendantInvalidationKind::Dom); > } > > match self.selector.combinator_at_parse_order(self.offset - 1) { > Combinator::Child | Combinator::Descendant | Combinator::PseudoElement => { > InvalidationKind::Descendant(DescendantInvalidationKind::Dom) >- }, >+ } > Combinator::SlotAssignment => { > InvalidationKind::Descendant(DescendantInvalidationKind::Slotted) >- }, >+ } > Combinator::NextSibling | Combinator::LaterSibling => InvalidationKind::Sibling, > } > } > } > > impl<'a> fmt::Debug for Invalidation<'a> { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > use cssparser::ToCss; >@@ -689,17 +689,17 @@ where > > let mut invalidated_self = false; > let mut matched = false; > match matching_result { > CompoundSelectorMatchingResult::FullyMatched => { > debug!(" > Invalidation matched completely"); > matched = true; > invalidated_self = true; >- }, >+ } > CompoundSelectorMatchingResult::Matched { > next_combinator_offset, > } => { > let next_combinator = invalidation > .selector > .combinator_at_parse_order(next_combinator_offset); > matched = true; > >@@ -809,44 +809,44 @@ where > // > // [div div div, div div, div div, div] > // > // While skipping it, we won't arrive here with duplicating > // dependencies: > // > // [div div div, div div, div] > // >- let can_skip_pushing = next_invalidation_kind == invalidation_kind && >- invalidation.matched_by_any_previous && >- next_invalidation.effective_for_next(); >+ let can_skip_pushing = next_invalidation_kind == invalidation_kind >+ && invalidation.matched_by_any_previous >+ && next_invalidation.effective_for_next(); > > if can_skip_pushing { > debug!( > " > Can avoid push, since the invalidation had \ > already been matched before" > ); > } else { > match next_invalidation_kind { > InvalidationKind::Descendant(DescendantInvalidationKind::Dom) => { > descendant_invalidations > .dom_descendants > .push(next_invalidation); >- }, >+ } > InvalidationKind::Descendant(DescendantInvalidationKind::Slotted) => { > descendant_invalidations > .slotted_descendants > .push(next_invalidation); >- }, >+ } > InvalidationKind::Sibling => { > sibling_invalidations.push(next_invalidation); >- }, >+ } > } > } >- }, >- CompoundSelectorMatchingResult::NotMatched => {}, >+ } >+ CompoundSelectorMatchingResult::NotMatched => {} > } > > SingleInvalidationResult { > invalidated_self, > matched, > } > } > } >diff --git a/servo/components/style/invalidation/element/restyle_hints.rs b/servo/components/style/invalidation/element/restyle_hints.rs >index 4ac06c8b1631..ec241d40d3f1 100644 >--- a/servo/components/style/invalidation/element/restyle_hints.rs >+++ b/servo/components/style/invalidation/element/restyle_hints.rs >@@ -62,18 +62,19 @@ impl RestyleHint { > /// descendants. > pub fn contains_subtree(&self) -> bool { > self.contains(RestyleHint::RESTYLE_SELF | RestyleHint::RESTYLE_DESCENDANTS) > } > > /// Returns whether we need to restyle this element. > pub fn has_non_animation_invalidations(&self) -> bool { > self.intersects( >- RestyleHint::RESTYLE_SELF | RestyleHint::RECASCADE_SELF | >- (Self::replacements() & !Self::for_animations()), >+ RestyleHint::RESTYLE_SELF >+ | RestyleHint::RECASCADE_SELF >+ | (Self::replacements() & !Self::for_animations()), > ) > } > > /// Propagates this restyle hint to a child element. > pub fn propagate(&mut self, traversal_flags: &TraversalFlags) -> Self { > use std::mem; > > // In the middle of an animation only restyle, we don't need to >@@ -114,18 +115,19 @@ impl RestyleHint { > /// Returns a hint that contains all the replacement hints. > pub fn replacements() -> Self { > RestyleHint::RESTYLE_STYLE_ATTRIBUTE | Self::for_animations() > } > > /// The replacements for the animation cascade levels. > #[inline] > pub fn for_animations() -> Self { >- RestyleHint::RESTYLE_SMIL | RestyleHint::RESTYLE_CSS_ANIMATIONS | >- RestyleHint::RESTYLE_CSS_TRANSITIONS >+ RestyleHint::RESTYLE_SMIL >+ | RestyleHint::RESTYLE_CSS_ANIMATIONS >+ | RestyleHint::RESTYLE_CSS_TRANSITIONS > } > > /// Returns whether the hint specifies that the currently element must be > /// recascaded. > pub fn has_recascade_self(&self) -> bool { > self.contains(RestyleHint::RECASCADE_SELF) > } > >diff --git a/servo/components/style/invalidation/element/state_and_attributes.rs b/servo/components/style/invalidation/element/state_and_attributes.rs >index 1eb022b298a7..76a17bb3b2da 100644 >--- a/servo/components/style/invalidation/element/state_and_attributes.rs >+++ b/servo/components/style/invalidation/element/state_and_attributes.rs >@@ -1,33 +1,33 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! An invalidation processor for style changes due to state and attribute > //! changes. > >-use {Atom, WeakAtom}; > use context::SharedStyleContext; > use data::ElementData; > use dom::TElement; > use element_state::ElementState; > use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper}; > use invalidation::element::invalidation_map::*; > use invalidation::element::invalidator::{DescendantInvalidationLists, InvalidationVector}; > use invalidation::element::invalidator::{Invalidation, InvalidationProcessor}; > use invalidation::element::restyle_hints::RestyleHint; > use selector_map::SelectorMap; > use selector_parser::Snapshot; >-use selectors::NthIndexCache; > use selectors::attr::CaseSensitivity; >-use selectors::matching::{MatchingContext, MatchingMode, VisitedHandlingMode}; > use selectors::matching::matches_selector; >+use selectors::matching::{MatchingContext, MatchingMode, VisitedHandlingMode}; >+use selectors::NthIndexCache; > use smallvec::SmallVec; > use stylesheets::origin::{Origin, OriginSet}; >+use {Atom, WeakAtom}; > > /// The collector implementation. > struct Collector<'a, 'b: 'a, 'selectors: 'a, E> > where > E: TElement, > { > element: E, > wrapper: ElementWrapper<'b, E>, >@@ -201,27 +201,22 @@ where > } > > if log_enabled!(::log::Level::Debug) { > debug!("Collecting changes for: {:?}", element); > if !state_changes.is_empty() { > debug!(" > state: {:?}", state_changes); > } > if snapshot.id_changed() { >- debug!( >- " > id changed: +{:?} -{:?}", >- id_added, >- id_removed >- ); >+ debug!(" > id changed: +{:?} -{:?}", id_added, id_removed); > } > if snapshot.class_changed() { > debug!( > " > class changed: +{:?} -{:?}", >- classes_added, >- classes_removed >+ classes_added, classes_removed > ); > } > if snapshot.other_attr_changed() { > debug!( > " > attributes changed, old: {}", > snapshot.debug_list_attributes() > ) > } >@@ -234,17 +229,16 @@ where > }; > > let mut shadow_rule_datas = SmallVec::<[_; 3]>::new(); > let matches_document_author_rules = > element.each_applicable_non_document_style_rule_data(|data, quirks_mode, host| { > shadow_rule_datas.push((data, quirks_mode, host.map(|h| h.opaque()))) > }); > >- > let invalidated_self = { > let mut collector = Collector { > wrapper, > lookup_element, > state_changes, > element, > snapshot: &snapshot, > matching_context: &mut self.matching_context, >@@ -363,19 +357,19 @@ where > for class in self.classes_added.iter().chain(self.classes_removed.iter()) { > if let Some(deps) = map.class_to_selector.get(class, quirks_mode) { > for dep in deps { > self.scan_dependency(dep); > } > } > } > >- let should_examine_attribute_selector_map = self.snapshot.other_attr_changed() || >- (self.snapshot.class_changed() && map.has_class_attribute_selectors) || >- (self.snapshot.id_changed() && map.has_id_attribute_selectors); >+ let should_examine_attribute_selector_map = self.snapshot.other_attr_changed() >+ || (self.snapshot.class_changed() && map.has_class_attribute_selectors) >+ || (self.snapshot.id_changed() && map.has_id_attribute_selectors); > > if should_examine_attribute_selector_map { > self.collect_dependencies_in_map(&map.other_attribute_affecting_selectors) > } > > let state_changes = self.state_changes; > if !state_changes.is_empty() { > self.collect_state_dependencies(&map.state_affecting_selectors, state_changes) >@@ -411,20 +405,17 @@ where > } > self.scan_dependency(&dependency.dep); > true > }, > ); > } > > /// Check whether a dependency should be taken into account. >- fn check_dependency( >- &mut self, >- dependency: &Dependency, >- ) -> bool { >+ fn check_dependency(&mut self, dependency: &Dependency) -> bool { > let element = &self.element; > let wrapper = &self.wrapper; > let matches_now = matches_selector( > &dependency.selector, > dependency.selector_offset, > None, > element, > &mut self.matching_context, >@@ -477,37 +468,37 @@ where > > match invalidation_kind { > DependencyInvalidationKind::Element => unreachable!(), > DependencyInvalidationKind::ElementAndDescendants => { > self.invalidates_self = true; > self.descendant_invalidations > .dom_descendants > .push(invalidation); >- }, >+ } > DependencyInvalidationKind::Descendants => { > self.descendant_invalidations > .dom_descendants > .push(invalidation); >- }, >+ } > DependencyInvalidationKind::Siblings => { > self.sibling_invalidations.push(invalidation); >- }, >+ } > DependencyInvalidationKind::SlottedElements => { > self.descendant_invalidations > .slotted_descendants > .push(invalidation); >- }, >+ } > } > } > > /// Returns whether `dependency` may cause us to invalidate the style of > /// more elements than what we've already invalidated. > fn dependency_may_be_relevant(&self, dependency: &Dependency) -> bool { > match dependency.invalidation_kind() { > DependencyInvalidationKind::Element => !self.invalidates_self, > DependencyInvalidationKind::SlottedElements => self.element.is_html_slot_element(), >- DependencyInvalidationKind::ElementAndDescendants | >- DependencyInvalidationKind::Siblings | >- DependencyInvalidationKind::Descendants => true, >+ DependencyInvalidationKind::ElementAndDescendants >+ | DependencyInvalidationKind::Siblings >+ | DependencyInvalidationKind::Descendants => true, > } > } > } >diff --git a/servo/components/style/invalidation/stylesheets.rs b/servo/components/style/invalidation/stylesheets.rs >index 1889d325630f..802156e171bf 100644 >--- a/servo/components/style/invalidation/stylesheets.rs >+++ b/servo/components/style/invalidation/stylesheets.rs >@@ -2,29 +2,29 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A collection of invalidations due to changes in which stylesheets affect a > //! document. > > #![deny(unsafe_code)] > >-use Atom; >-use CaseSensitivityExt; >-use LocalName as SelectorLocalName; > use dom::{TDocument, TElement, TNode}; > use fxhash::FxHashSet; > use invalidation::element::element_wrapper::{ElementSnapshot, ElementWrapper}; > use invalidation::element::restyle_hints::RestyleHint; > use media_queries::Device; > use selector_parser::{SelectorImpl, Snapshot, SnapshotMap}; > use selectors::attr::CaseSensitivity; > use selectors::parser::{Component, LocalName, Selector}; > use shared_lock::SharedRwLockReadGuard; > use stylesheets::{CssRule, StylesheetInDocument}; >+use Atom; >+use CaseSensitivityExt; >+use LocalName as SelectorLocalName; > > /// A style sheet invalidation represents a kind of element or subtree that may > /// need to be restyled. Whether it represents a whole subtree or just a single > /// element is determined by whether the invalidation is stored in the > /// StylesheetInvalidationSet's invalid_scopes or invalid_elements table. > #[derive(Debug, Eq, Hash, MallocSizeOf, PartialEq)] > enum Invalidation { > /// An element with a given id. >@@ -62,42 +62,42 @@ impl Invalidation { > return true; > } > > if let Some(snapshot) = snapshot { > if snapshot.has_class(class, case_sensitivity) { > return true; > } > } >- }, >+ } > Invalidation::ID(ref id) => { > if let Some(ref element_id) = element.id() { > if case_sensitivity.eq_atom(element_id, id) { > return true; > } > } > > if let Some(snapshot) = snapshot { > if let Some(ref old_id) = snapshot.id_attr() { > if case_sensitivity.eq_atom(old_id, id) { > return true; > } > } > } >- }, >+ } > Invalidation::LocalName { > ref name, > ref lower_name, > } => { > // This could look at the quirks mode of the document, instead > // of testing against both names, but it's probably not worth > // it. > let local_name = element.local_name(); > return *local_name == **name || *local_name == **lower_name; >- }, >+ } > } > > false > } > } > > /// A set of invalidations due to stylesheet additions. > /// >@@ -331,30 +331,30 @@ impl StylesheetInvalidationSet { > ref lower_name, > }) => { > if invalidation.as_ref().map_or(true, |s| !s.is_id_or_class()) { > *invalidation = Some(Invalidation::LocalName { > name: name.clone(), > lower_name: lower_name.clone(), > }); > } >- }, >+ } > Component::Class(ref class) => { > if invalidation.as_ref().map_or(true, |s| !s.is_id()) { > *invalidation = Some(Invalidation::Class(class.clone())); > } >- }, >+ } > Component::ID(ref id) => { > if invalidation.is_none() { > *invalidation = Some(Invalidation::ID(id.clone())); > } >- }, >+ } > _ => { > // Ignore everything else, at least for now. >- }, >+ } > } > } > > /// Collect invalidations for a given selector. > /// > /// We look at the outermost local name, class, or ID selector to the left > /// of an ancestor combinator, in order to restyle only a given subtree. > /// >@@ -388,17 +388,17 @@ impl StylesheetInvalidationSet { > } else if scan_for_subtree_invalidation { > Self::scan_component(component, &mut subtree_invalidation); > } > } > match iter.next_sequence() { > None => break, > Some(combinator) => { > scan_for_subtree_invalidation = combinator.is_ancestor(); >- }, >+ } > } > scan_for_element_invalidation = false; > } > > if let Some(s) = subtree_invalidation { > debug!(" > Found subtree invalidation: {:?}", s); > self.invalid_scopes.insert(s); > } else if let Some(s) = element_invalidation { >@@ -427,46 +427,46 @@ impl StylesheetInvalidationSet { > Style(ref lock) => { > let style_rule = lock.read_with(guard); > for selector in &style_rule.selectors.0 { > self.collect_invalidations(selector); > if self.fully_invalid { > return; > } > } >- }, >+ } > Document(..) | Namespace(..) | Import(..) | Media(..) | Supports(..) => { > // Do nothing, relevant nested rules are visited as part of the > // iteration. >- }, >+ } > FontFace(..) => { > // Do nothing, @font-face doesn't affect computed style > // information. We'll restyle when the font face loads, if > // needed. >- }, >+ } > Keyframes(ref lock) => { > let keyframes_rule = lock.read_with(guard); > if device.animation_name_may_be_referenced(&keyframes_rule.name) { > debug!( > " > Found @keyframes rule potentially referenced \ > from the page, marking the whole tree invalid." > ); > self.fully_invalid = true; > } else { > // Do nothing, this animation can't affect the style of > // existing elements. > } >- }, >+ } > CounterStyle(..) | Page(..) | Viewport(..) | FontFeatureValues(..) => { > debug!( > " > Found unsupported rule, marking the whole subtree \ > invalid." > ); > > // TODO(emilio): Can we do better here? > // > // At least in `@page`, we could check the relevant media, I > // guess. > self.fully_invalid = true; >- }, >+ } > } > } > } >diff --git a/servo/components/style/lib.rs b/servo/components/style/lib.rs >index 1c3630b09864..a9b2deafd5e2 100644 >--- a/servo/components/style/lib.rs >+++ b/servo/components/style/lib.rs >@@ -161,30 +161,30 @@ pub mod traversal_flags; > #[allow(non_camel_case_types)] > pub mod values; > > #[cfg(feature = "gecko")] > pub use gecko_string_cache as string_cache; > #[cfg(feature = "gecko")] > pub use gecko_string_cache::Atom; > #[cfg(feature = "gecko")] >-pub use gecko_string_cache::Namespace; >-#[cfg(feature = "gecko")] > pub use gecko_string_cache::Atom as Prefix; > #[cfg(feature = "gecko")] > pub use gecko_string_cache::Atom as LocalName; >+#[cfg(feature = "gecko")] >+pub use gecko_string_cache::Namespace; > >-#[cfg(feature = "servo")] >-pub use servo_atoms::Atom; >-#[cfg(feature = "servo")] >-pub use html5ever::Prefix; > #[cfg(feature = "servo")] > pub use html5ever::LocalName; > #[cfg(feature = "servo")] > pub use html5ever::Namespace; >+#[cfg(feature = "servo")] >+pub use html5ever::Prefix; >+#[cfg(feature = "servo")] >+pub use servo_atoms::Atom; > > /// The CSS properties supported by the style system. > /// Generated from the properties.mako.rs template by build.rs > #[macro_use] > #[allow(unsafe_code)] > #[deny(missing_docs)] > pub mod properties { > include!(concat!(env!("OUT_DIR"), "/properties.rs")); >@@ -194,17 +194,16 @@ pub mod properties { > #[allow(unsafe_code)] > pub mod gecko; > > // uses a macro from properties > #[cfg(feature = "servo")] > #[allow(unsafe_code)] > pub mod servo; > >- > #[cfg(feature = "gecko")] > #[allow(unsafe_code, missing_docs)] > pub mod gecko_properties { > include!(concat!(env!("OUT_DIR"), "/gecko_properties.rs")); > } > > macro_rules! reexport_computed_values { > ( $( { $name: ident, $boxed: expr } )+ ) => { >diff --git a/servo/components/style/logical_geometry.rs b/servo/components/style/logical_geometry.rs >index b345c2ad3752..5d12ac21af40 100644 >--- a/servo/components/style/logical_geometry.rs >+++ b/servo/components/style/logical_geometry.rs >@@ -1,16 +1,16 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Geometry in flow-relative space. > >-use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; > use euclid::num::Zero; >+use euclid::{Point2D, Rect, SideOffsets2D, Size2D}; > use properties::style_structs; > use std::cmp::{max, min}; > use std::fmt::{self, Debug, Error, Formatter}; > use std::ops::{Add, Sub}; > use unicode_bidi as bidi; > > pub enum BlockFlowDirection { > TopToBottom, >@@ -43,61 +43,61 @@ impl WritingMode { > /// Return a WritingMode bitflags from the relevant CSS properties. > pub fn new(inheritedbox_style: &style_structs::InheritedBox) -> Self { > use properties::longhands::direction::computed_value::T as Direction; > use properties::longhands::writing_mode::computed_value::T as SpecifiedWritingMode; > > let mut flags = WritingMode::empty(); > > match inheritedbox_style.clone_direction() { >- Direction::Ltr => {}, >+ Direction::Ltr => {} > Direction::Rtl => { > flags.insert(WritingMode::RTL); >- }, >+ } > } > > match inheritedbox_style.clone_writing_mode() { >- SpecifiedWritingMode::HorizontalTb => {}, >+ SpecifiedWritingMode::HorizontalTb => {} > SpecifiedWritingMode::VerticalRl => { > flags.insert(WritingMode::VERTICAL); >- }, >+ } > SpecifiedWritingMode::VerticalLr => { > flags.insert(WritingMode::VERTICAL); > flags.insert(WritingMode::VERTICAL_LR); >- }, >+ } > #[cfg(feature = "gecko")] > SpecifiedWritingMode::SidewaysRl => { > flags.insert(WritingMode::VERTICAL); > flags.insert(WritingMode::SIDEWAYS); >- }, >+ } > #[cfg(feature = "gecko")] > SpecifiedWritingMode::SidewaysLr => { > flags.insert(WritingMode::VERTICAL); > flags.insert(WritingMode::VERTICAL_LR); > flags.insert(WritingMode::LINE_INVERTED); > flags.insert(WritingMode::SIDEWAYS); >- }, >+ } > } > > #[cfg(feature = "gecko")] > { > use properties::longhands::text_orientation::computed_value::T as TextOrientation; > > // If FLAG_SIDEWAYS is already set, this means writing-mode is > // either sideways-rl or sideways-lr, and for both of these values, > // text-orientation has no effect. > if !flags.intersects(WritingMode::SIDEWAYS) { > match inheritedbox_style.clone_text_orientation() { >- TextOrientation::Mixed => {}, >+ TextOrientation::Mixed => {} > TextOrientation::Upright => { > flags.insert(WritingMode::UPRIGHT); >- }, >+ } > TextOrientation::Sideways => { > flags.insert(WritingMode::SIDEWAYS); >- }, >+ } > } > } > } > > flags > } > > #[inline] >@@ -952,18 +952,20 @@ impl<T: Copy> LogicalMargin<T> { > LogicalMargin::from_physical(mode_to, self.to_physical(mode_from)) > } > } > } > > impl<T: PartialEq + Zero> LogicalMargin<T> { > #[inline] > pub fn is_zero(&self) -> bool { >- self.block_start == Zero::zero() && self.inline_end == Zero::zero() && >- self.block_end == Zero::zero() && self.inline_start == Zero::zero() >+ self.block_start == Zero::zero() >+ && self.inline_end == Zero::zero() >+ && self.block_end == Zero::zero() >+ && self.inline_start == Zero::zero() > } > } > > impl<T: Copy + Add<T, Output = T>> LogicalMargin<T> { > #[inline] > pub fn inline_start_end(&self) -> T { > self.inline_start + self.inline_end > } >diff --git a/servo/components/style/macros.rs b/servo/components/style/macros.rs >index 671ba35b8bc0..588893893365 100644 >--- a/servo/components/style/macros.rs >+++ b/servo/components/style/macros.rs >@@ -63,19 +63,29 @@ macro_rules! try_match_ident_ignore_ascii_case { > )) > } > }} > } > > macro_rules! define_keyword_type { > ($name:ident, $css:expr) => { > #[allow(missing_docs)] >- #[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+ #[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+ )] > pub struct $name; > > impl fmt::Debug for $name { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > f.write_str($css) > } > } > >diff --git a/servo/components/style/matching.rs b/servo/components/style/matching.rs >index 6f239d361d86..4684da864f41 100644 >--- a/servo/components/style/matching.rs >+++ b/servo/components/style/matching.rs >@@ -7,18 +7,18 @@ > #![allow(unsafe_code)] > #![deny(missing_docs)] > > use context::{ElementCascadeInputs, QuirksMode, SelectorFlagsMap}; > use context::{SharedStyleContext, StyleContext}; > use data::ElementData; > use dom::TElement; > use invalidation::element::restyle_hints::RestyleHint; >-use properties::ComputedValues; > use properties::longhands::display::computed_value::T as Display; >+use properties::ComputedValues; > use rule_tree::{CascadeLevel, StrongRuleNode}; > use selector_parser::{PseudoElement, RestyleDamage}; > use selectors::matching::ElementSelectorFlags; > use servo_arc::{Arc, ArcBorrow}; > use style_resolver::ResolvedElementStyles; > use traversal_flags::TraversalFlags; > > /// Represents the result of comparing an element's old and new style. >@@ -92,18 +92,18 @@ trait PrivateMatchMethods: TElement { > context: &mut StyleContext<Self>, > cascade_visited: CascadeVisitedMode, > cascade_inputs: &mut ElementCascadeInputs, > ) -> bool { > use properties::PropertyDeclarationBlock; > use shared_lock::Locked; > > debug_assert!( >- replacements.intersects(RestyleHint::replacements()) && >- (replacements & !RestyleHint::replacements()).is_empty() >+ replacements.intersects(RestyleHint::replacements()) >+ && (replacements & !RestyleHint::replacements()).is_empty() > ); > > let stylist = &context.shared.stylist; > let guards = &context.shared.guards; > > let primary_rules = match cascade_visited { > CascadeVisitedMode::Unvisited => cascade_inputs.primary.rules.as_mut(), > CascadeVisitedMode::Visited => cascade_inputs.primary.visited_rules.as_mut(), >@@ -351,20 +351,19 @@ trait PrivateMatchMethods: TElement { > // Bug 868975: These steps should examine and update the visited styles > // in addition to the unvisited styles. > > let mut tasks = UpdateAnimationsTasks::empty(); > if self.needs_animations_update(context, old_values.as_ref().map(|s| &**s), new_values) { > tasks.insert(UpdateAnimationsTasks::CSS_ANIMATIONS); > } > >- let before_change_style = if self.might_need_transitions_update( >- old_values.as_ref().map(|s| &**s), >- new_values, >- ) { >+ let before_change_style = if self >+ .might_need_transitions_update(old_values.as_ref().map(|s| &**s), new_values) >+ { > let after_change_style = if self.has_css_transitions() { > self.after_change_style(context, new_values) > } else { > None > }; > > // In order to avoid creating a SequentialTask for transitions which > // may not be updated, we check it per property to make sure Gecko >@@ -464,19 +463,21 @@ trait PrivateMatchMethods: TElement { > &self, > shared_context: &SharedStyleContext, > damage: &mut RestyleDamage, > old_values: &ComputedValues, > new_values: &ComputedValues, > pseudo: Option<&PseudoElement>, > ) -> ChildCascadeRequirement { > debug!("accumulate_damage_for: {:?}", self); >- debug_assert!(!shared_context >- .traversal_flags >- .contains(TraversalFlags::Forgetful)); >+ debug_assert!( >+ !shared_context >+ .traversal_flags >+ .contains(TraversalFlags::Forgetful) >+ ); > > let difference = self.compute_style_difference(old_values, new_values, pseudo); > > *damage |= difference.damage; > > debug!(" > style difference: {:?}", difference); > > // We need to cascade the children in order to ensure the correct >@@ -492,17 +493,17 @@ trait PrivateMatchMethods: TElement { > match difference.change { > StyleChange::Unchanged => return ChildCascadeRequirement::CanSkipCascade, > StyleChange::Changed { reset_only } => { > // If inherited properties changed, the best we can do is > // cascade the children. > if !reset_only { > return ChildCascadeRequirement::MustCascadeChildren; > } >- }, >+ } > } > > let old_display = old_values.get_box().clone_display(); > let new_display = new_values.get_box().clone_display(); > > // If we used to be a display: none element, and no longer are, > // our children need to be restyled because they're unstyled. > // >@@ -768,33 +769,33 @@ pub trait MatchMethods: TElement { > (&Some(ref old), &Some(ref new)) => { > self.accumulate_damage_for( > context.shared, > &mut data.damage, > old, > new, > Some(&PseudoElement::from_eager_index(i)), > ); >- }, >- (&None, &None) => {}, >+ } >+ (&None, &None) => {} > _ => { > // It's possible that we're switching from not having > // ::before/::after at all to having styles for them but not > // actually having a useful pseudo-element. Check for that > // case. > let pseudo = PseudoElement::from_eager_index(i); > let new_pseudo_should_exist = > new.as_ref().map_or(false, |s| pseudo.should_exist(s)); > let old_pseudo_should_exist = > old.as_ref().map_or(false, |s| pseudo.should_exist(s)); > if new_pseudo_should_exist != old_pseudo_should_exist { > data.damage |= RestyleDamage::reconstruct(); > return cascade_requirement; > } >- }, >+ } > } > } > > cascade_requirement > } > > /// Applies selector flags to an element, deferring mutations of the parent > /// until after the traversal. >diff --git a/servo/components/style/media_queries/media_condition.rs b/servo/components/style/media_queries/media_condition.rs >index dbd677d0aee4..55e8779167b4 100644 >--- a/servo/components/style/media_queries/media_condition.rs >+++ b/servo/components/style/media_queries/media_condition.rs >@@ -1,22 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A media query condition: > //! > //! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition > >+use super::{Device, MediaFeatureExpression}; > use context::QuirksMode; > use cssparser::{Parser, Token}; > use parser::ParserContext; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; >-use super::{Device, MediaFeatureExpression}; > > /// A binary `and` or `or` operator. > #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss)] > #[allow(missing_docs)] > pub enum Operator { > And, > Or, > } >@@ -99,24 +99,22 @@ impl MediaCondition { > allow_or: AllowOr, > ) -> Result<Self, ParseError<'i>> { > let location = input.current_source_location(); > > // FIXME(emilio): This can be cleaner with nll. > let is_negation = match *input.next()? { > Token::ParenthesisBlock => false, > Token::Ident(ref ident) if ident.eq_ignore_ascii_case("not") => true, >- ref t => { >- return Err(location.new_unexpected_token_error(t.clone())) >- } >+ ref t => return Err(location.new_unexpected_token_error(t.clone())), > }; > > if is_negation { > let inner_condition = Self::parse_in_parens(context, input)?; >- return Ok(MediaCondition::Not(Box::new(inner_condition))) >+ return Ok(MediaCondition::Not(Box::new(inner_condition))); > } > > // ParenthesisBlock. > let first_condition = Self::parse_paren_block(context, input)?; > let operator = match input.try(Operator::parse) { > Ok(op) => op, > Err(..) => return Ok(first_condition), > }; >@@ -157,35 +155,31 @@ impl MediaCondition { > > fn parse_paren_block<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > input.parse_nested_block(|input| { > // Base case. > if let Ok(inner) = input.try(|i| Self::parse(context, i)) { >- return Ok(MediaCondition::InParens(Box::new(inner))) >+ return Ok(MediaCondition::InParens(Box::new(inner))); > } > let expr = MediaFeatureExpression::parse_in_parenthesis_block(context, input)?; > Ok(MediaCondition::Feature(expr)) > }) > } > > /// Whether this condition matches the device and quirks mode. > pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool { > match *self { > MediaCondition::Feature(ref f) => f.matches(device, quirks_mode), > MediaCondition::InParens(ref c) => c.matches(device, quirks_mode), > MediaCondition::Not(ref c) => !c.matches(device, quirks_mode), > MediaCondition::Operation(ref conditions, op) => { > let mut iter = conditions.iter(); > match op { >- Operator::And => { >- iter.all(|c| c.matches(device, quirks_mode)) >- } >- Operator::Or => { >- iter.any(|c| c.matches(device, quirks_mode)) >- } >+ Operator::And => iter.all(|c| c.matches(device, quirks_mode)), >+ Operator::Or => iter.any(|c| c.matches(device, quirks_mode)), > } > } > } > } > } >diff --git a/servo/components/style/media_queries/media_feature.rs b/servo/components/style/media_queries/media_feature.rs >index 7c0bfc12bef4..82ec236a87d0 100644 >--- a/servo/components/style/media_queries/media_feature.rs >+++ b/servo/components/style/media_queries/media_feature.rs >@@ -1,23 +1,23 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Media features. > >-use super::Device; > use super::media_feature_expression::{AspectRatio, RangeOrOperator}; >+use super::Device; > >-use Atom; > use cssparser::Parser; > use parser::ParserContext; > use std::fmt; > use style_traits::ParseError; > use values::computed::{CSSPixelLength, Resolution}; >+use Atom; > > /// A generic discriminant for an enum value. > pub type KeywordDiscriminant = u8; > > type MediaFeatureEvaluator<T> = fn( > device: &Device, > // null == no value was given in the query. > value: Option<T>, >@@ -26,20 +26,19 @@ type MediaFeatureEvaluator<T> = fn( > > /// Serializes a given discriminant. > /// > /// FIXME(emilio): we could prevent this allocation if the ToCss code would > /// generate a method for keywords to get the static string or something. > pub type KeywordSerializer = fn(KeywordDiscriminant) -> String; > > /// Parses a given identifier. >-pub type KeywordParser = for <'a, 'i, 't> fn( >- context: &'a ParserContext, >- input: &'a mut Parser<'i, 't>, >-) -> Result<KeywordDiscriminant, ParseError<'i>>; >+pub type KeywordParser = >+ for<'a, 'i, 't> fn(context: &'a ParserContext, input: &'a mut Parser<'i, 't>) >+ -> Result<KeywordDiscriminant, ParseError<'i>>; > > /// An evaluator for a given media feature. > /// > /// This determines the kind of values that get parsed, too. > #[allow(missing_docs)] > pub enum Evaluator { > Length(MediaFeatureEvaluator<CSSPixelLength>), > Integer(MediaFeatureEvaluator<u32>), >@@ -66,60 +65,59 @@ pub enum Evaluator { > } > > /// A simple helper macro to create a keyword evaluator. > /// > /// This assumes that keyword feature expressions don't accept ranges, and > /// asserts if that's not true. As of today there's nothing like that (does that > /// even make sense?). > macro_rules! keyword_evaluator { >- ($actual_evaluator:ident, $keyword_type:ty) => { >- { >- fn __parse<'i, 't>( >- context: &$crate::parser::ParserContext, >- input: &mut $crate::cssparser::Parser<'i, 't>, >- ) -> Result< >- $crate::media_queries::media_feature::KeywordDiscriminant, >- ::style_traits::ParseError<'i>, >- > { >- let kw = <$keyword_type as $crate::parser::Parse>::parse(context, input)?; >- Ok(kw as $crate::media_queries::media_feature::KeywordDiscriminant) >- } >+ ($actual_evaluator:ident, $keyword_type:ty) => {{ >+ fn __parse<'i, 't>( >+ context: &$crate::parser::ParserContext, >+ input: &mut $crate::cssparser::Parser<'i, 't>, >+ ) -> Result< >+ $crate::media_queries::media_feature::KeywordDiscriminant, >+ ::style_traits::ParseError<'i>, >+ > { >+ let kw = <$keyword_type as $crate::parser::Parse>::parse(context, input)?; >+ Ok(kw as $crate::media_queries::media_feature::KeywordDiscriminant) >+ } > >- fn __serialize(kw: $crate::media_queries::media_feature::KeywordDiscriminant) -> String { >- // This unwrap is ok because the only discriminants that get >- // back to us is the ones that `parse` produces. >- let value: $keyword_type = >- ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap(); >- <$keyword_type as ::style_traits::ToCss>::to_css_string(&value) >- } >+ fn __serialize(kw: $crate::media_queries::media_feature::KeywordDiscriminant) -> String { >+ // This unwrap is ok because the only discriminants that get >+ // back to us is the ones that `parse` produces. >+ let value: $keyword_type = ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap(); >+ <$keyword_type as ::style_traits::ToCss>::to_css_string(&value) >+ } > >- fn __evaluate( >- device: &$crate::media_queries::Device, >- value: Option<$crate::media_queries::media_feature::KeywordDiscriminant>, >- range_or_operator: Option<$crate::media_queries::media_feature_expression::RangeOrOperator>, >- ) -> bool { >- debug_assert!( >- range_or_operator.is_none(), >- "Since when do keywords accept ranges?" >- ); >- // This unwrap is ok because the only discriminants that get >- // back to us is the ones that `parse` produces. >- let value: Option<$keyword_type> = >- value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap()); >- $actual_evaluator(device, value) >- } >+ fn __evaluate( >+ device: &$crate::media_queries::Device, >+ value: Option<$crate::media_queries::media_feature::KeywordDiscriminant>, >+ range_or_operator: Option< >+ $crate::media_queries::media_feature_expression::RangeOrOperator, >+ >, >+ ) -> bool { >+ debug_assert!( >+ range_or_operator.is_none(), >+ "Since when do keywords accept ranges?" >+ ); >+ // This unwrap is ok because the only discriminants that get >+ // back to us is the ones that `parse` produces. >+ let value: Option<$keyword_type> = >+ value.map(|kw| ::num_traits::cast::FromPrimitive::from_u8(kw).unwrap()); >+ $actual_evaluator(device, value) >+ } > >- $crate::media_queries::media_feature::Evaluator::Enumerated { >- parser: __parse, >- serializer: __serialize, >- evaluator: __evaluate, >- } >+ $crate::media_queries::media_feature::Evaluator::Enumerated { >+ parser: __parse, >+ serializer: __serialize, >+ evaluator: __evaluate, > } >- } >+ }}; > } > > bitflags! { > /// Different requirements or toggles that change how a expression is > /// parsed. > pub struct ParsingRequirements: u8 { > /// The feature should only be parsed in chrome and ua sheets. > const CHROME_AND_UA_ONLY = 1 << 0; >diff --git a/servo/components/style/media_queries/media_feature_expression.rs b/servo/components/style/media_queries/media_feature_expression.rs >index 81bbb69c1a10..853cae35957a 100644 >--- a/servo/components/style/media_queries/media_feature_expression.rs >+++ b/servo/components/style/media_queries/media_feature_expression.rs >@@ -1,32 +1,32 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Parsing for media feature expressions, like `(foo: bar)` or > //! `(width >= 400px)`. > >-use super::Device; > use super::media_feature::{Evaluator, MediaFeatureDescription}; >-use super::media_feature::{ParsingRequirements, KeywordDiscriminant}; >+use super::media_feature::{KeywordDiscriminant, ParsingRequirements}; >+use super::Device; > >-use Atom; >-use cssparser::{Parser, Token}; > use context::QuirksMode; >+use cssparser::{Parser, Token}; > use num_traits::Zero; > use parser::{Parse, ParserContext}; >-use std::cmp::{PartialOrd, Ordering}; >+use std::cmp::{Ordering, PartialOrd}; > use std::fmt::{self, Write}; > use str::{starts_with_ignore_ascii_case, string_as_ascii_lowercase}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use stylesheets::Origin; >-use values::{serialize_atom_identifier, CSSFloat}; >-use values::specified::{Integer, Length, Number, Resolution}; > use values::computed::{self, ToComputedValue}; >+use values::specified::{Integer, Length, Number, Resolution}; >+use values::{serialize_atom_identifier, CSSFloat}; >+use Atom; > > #[cfg(feature = "gecko")] > use gecko_bindings::structs; > > #[cfg(feature = "gecko")] > use gecko::media_features::MEDIA_FEATURES; > #[cfg(feature = "servo")] > use servo::media_queries::MEDIA_FEATURES; >@@ -104,37 +104,29 @@ pub enum RangeOrOperator { > Range(Range), > /// An `Operator`. > Operator(Operator), > } > > impl RangeOrOperator { > /// Evaluate a given range given an optional query value and a value from > /// the browser. >- pub fn evaluate<T>( >- range_or_op: Option<Self>, >- query_value: Option<T>, >- value: T, >- ) -> bool >+ pub fn evaluate<T>(range_or_op: Option<Self>, query_value: Option<T>, value: T) -> bool > where >- T: PartialOrd + Zero >+ T: PartialOrd + Zero, > { > match query_value { > Some(v) => Self::evaluate_with_query_value(range_or_op, v, value), > None => !value.is_zero(), > } > } > > /// Evaluate a given range given a non-optional query value and a value from > /// the browser. >- pub fn evaluate_with_query_value<T>( >- range_or_op: Option<Self>, >- query_value: T, >- value: T, >- ) -> bool >+ pub fn evaluate_with_query_value<T>(range_or_op: Option<Self>, query_value: T, value: T) -> bool > where > T: PartialOrd, > { > let cmp = match value.partial_cmp(&query_value) { > Some(c) => c, > None => return false, > }; > >@@ -145,58 +137,56 @@ impl RangeOrOperator { > > match range_or_op { > RangeOrOperator::Range(range) => { > cmp == Ordering::Equal || match range { > Range::Min => cmp == Ordering::Greater, > Range::Max => cmp == Ordering::Less, > } > } >- RangeOrOperator::Operator(op) => { >- match op { >- Operator::Equal => cmp == Ordering::Equal, >- Operator::GreaterThan => cmp == Ordering::Greater, >- Operator::GreaterThanEqual => { >- cmp == Ordering::Equal || cmp == Ordering::Greater >- } >- Operator::LessThan => cmp == Ordering::Less, >- Operator::LessThanEqual => { >- cmp == Ordering::Equal || cmp == Ordering::Less >- } >- } >- } >+ RangeOrOperator::Operator(op) => match op { >+ Operator::Equal => cmp == Ordering::Equal, >+ Operator::GreaterThan => cmp == Ordering::Greater, >+ Operator::GreaterThanEqual => cmp == Ordering::Equal || cmp == Ordering::Greater, >+ Operator::LessThan => cmp == Ordering::Less, >+ Operator::LessThanEqual => cmp == Ordering::Equal || cmp == Ordering::Less, >+ }, > } > } > } > > /// A feature expression contains a reference to the media feature, the value > /// the media query contained, and the range to evaluate. > #[derive(Clone, Debug, MallocSizeOf)] > pub struct MediaFeatureExpression { > feature: &'static MediaFeatureDescription, > value: Option<MediaExpressionValue>, > range_or_operator: Option<RangeOrOperator>, > } > > impl PartialEq for MediaFeatureExpression { > fn eq(&self, other: &Self) -> bool { >- self.feature as *const _ == other.feature as *const _ && >- self.value == other.value && >- self.range_or_operator == other.range_or_operator >+ self.feature as *const _ == other.feature as *const _ >+ && self.value == other.value >+ && self.range_or_operator == other.range_or_operator > } > } > > impl ToCss for MediaFeatureExpression { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: fmt::Write, > { > dest.write_str("(")?; > >- if self.feature.requirements.contains(ParsingRequirements::WEBKIT_PREFIX) { >+ if self >+ .feature >+ .requirements >+ .contains(ParsingRequirements::WEBKIT_PREFIX) >+ { > dest.write_str("-webkit-")?; > } > > if let Some(RangeOrOperator::Range(range)) = self.range_or_operator { > match range { > Range::Min => dest.write_str("min-")?, > Range::Max => dest.write_str("max-")?, > } >@@ -217,19 +207,17 @@ impl ToCss for MediaFeatureExpression { > val.to_css(dest, self)?; > } > > dest.write_str(")") > } > } > > /// Consumes an operation or a colon, or returns an error. >-fn consume_operation_or_colon( >- input: &mut Parser, >-) -> Result<Option<Operator>, ()> { >+fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, ()> { > let first_delim = { > let next_token = match input.next() { > Ok(t) => t, > Err(..) => return Err(()), > }; > > match *next_token { > Token::Colon => return Ok(None), >@@ -258,32 +246,34 @@ fn consume_operation_or_colon( > } > > impl MediaFeatureExpression { > fn new( > feature: &'static MediaFeatureDescription, > value: Option<MediaExpressionValue>, > range_or_operator: Option<RangeOrOperator>, > ) -> Self { >- Self { feature, value, range_or_operator } >+ Self { >+ feature, >+ value, >+ range_or_operator, >+ } > } > > /// Parse a media expression of the form: > /// > /// ``` > /// (media-feature: media-value) > /// ``` > pub fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > input.expect_parenthesis_block()?; >- input.parse_nested_block(|input| { >- Self::parse_in_parenthesis_block(context, input) >- }) >+ input.parse_nested_block(|input| Self::parse_in_parenthesis_block(context, input)) > } > > /// Parse a media feature expression where we've already consumed the > /// parenthesis. > pub fn parse_in_parenthesis_block<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { >@@ -291,36 +281,36 @@ impl MediaFeatureExpression { > let feature; > let range; > { > let location = input.current_source_location(); > let ident = input.expect_ident()?; > > let mut requirements = ParsingRequirements::empty(); > >- if context.chrome_rules_enabled() || >- context.stylesheet_origin == Origin::UserAgent >- { >+ if context.chrome_rules_enabled() || context.stylesheet_origin == Origin::UserAgent { > requirements.insert(ParsingRequirements::CHROME_AND_UA_ONLY); > } > > let result = { > let mut feature_name = &**ident; > > #[cfg(feature = "gecko")] > { >- if unsafe { structs::StaticPrefs_sVarCache_layout_css_prefixes_webkit } && >- starts_with_ignore_ascii_case(feature_name, "-webkit-") >+ if unsafe { structs::StaticPrefs_sVarCache_layout_css_prefixes_webkit } >+ && starts_with_ignore_ascii_case(feature_name, "-webkit-") > { > feature_name = &feature_name[8..]; > requirements.insert(ParsingRequirements::WEBKIT_PREFIX); > if unsafe { > structs::StaticPrefs_sVarCache_layout_css_prefixes_device_pixel_ratio_webkit > } { >- requirements.insert(ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED); >+ requirements.insert( >+ ParsingRequirements::WEBKIT_DEVICE_PIXEL_RATIO_PREF_ENABLED, >+ ); > } > } > } > > let range = if starts_with_ignore_ascii_case(feature_name, "min-") { > feature_name = &feature_name[4..]; > Some(Range::Min) > } else if starts_with_ignore_ascii_case(feature_name, "max-") { >@@ -336,22 +326,22 @@ impl MediaFeatureExpression { > None => Err(()), > } > }; > > match result { > Ok((f, r)) => { > feature = f; > range = r; >- }, >+ } > Err(()) => { > return Err(location.new_custom_error( > StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), > )) >- }, >+ } > } > > if !(feature.requirements & !requirements).is_empty() { > return Err(location.new_custom_error( > StyleParseErrorKind::MediaQueryExpectedFeatureName(ident.clone()), > )); > } > >@@ -367,113 +357,101 @@ impl MediaFeatureExpression { > Err(..) => { > // If there's no colon, this is a media query of the > // form '(<feature>)', that is, there's no value > // specified. > // > // Gecko doesn't allow ranged expressions without a > // value, so just reject them here too. > if range.is_some() { >- return Err(input.new_custom_error( >- StyleParseErrorKind::RangedExpressionWithNoValue >- )); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::RangedExpressionWithNoValue) >+ ); > } > > return Ok(Self::new(feature, None, None)); > } > Ok(operator) => operator, > }; > > let range_or_operator = match range { > Some(range) => { > if operator.is_some() { >- return Err(input.new_custom_error( >- StyleParseErrorKind::MediaQueryUnexpectedOperator >- )); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::MediaQueryUnexpectedOperator) >+ ); > } > Some(RangeOrOperator::Range(range)) > } >- None => { >- match operator { >- Some(operator) => { >- if !feature.allows_ranges() { >- return Err(input.new_custom_error( >- StyleParseErrorKind::MediaQueryUnexpectedOperator >- )); >- } >- Some(RangeOrOperator::Operator(operator)) >+ None => match operator { >+ Some(operator) => { >+ if !feature.allows_ranges() { >+ return Err(input >+ .new_custom_error(StyleParseErrorKind::MediaQueryUnexpectedOperator)); > } >- None => None, >+ Some(RangeOrOperator::Operator(operator)) > } >- } >+ None => None, >+ }, > }; > >- let value = >- MediaExpressionValue::parse(feature, context, input).map_err(|err| { >- err.location >- .new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue) >- })?; >+ let value = MediaExpressionValue::parse(feature, context, input).map_err(|err| { >+ err.location >+ .new_custom_error(StyleParseErrorKind::MediaQueryExpectedFeatureValue) >+ })?; > > Ok(Self::new(feature, Some(value), range_or_operator)) > } > > /// Returns whether this media query evaluates to true for the given device. > pub fn matches(&self, device: &Device, quirks_mode: QuirksMode) -> bool { > let value = self.value.as_ref(); > > macro_rules! expect { > ($variant:ident) => { >- value.map(|value| { >- match *value { >- MediaExpressionValue::$variant(ref v) => v, >- _ => unreachable!("Unexpected MediaExpressionValue"), >- } >+ value.map(|value| match *value { >+ MediaExpressionValue::$variant(ref v) => v, >+ _ => unreachable!("Unexpected MediaExpressionValue"), > }) >- } >+ }; > } > > match self.feature.evaluator { > Evaluator::Length(eval) => { > let computed = expect!(Length).map(|specified| { > computed::Context::for_media_query_evaluation(device, quirks_mode, |context| { > specified.to_computed_value(context) > }) > }); > eval(device, computed, self.range_or_operator) > } > Evaluator::Integer(eval) => { > eval(device, expect!(Integer).cloned(), self.range_or_operator) > } >- Evaluator::Float(eval) => { >- eval(device, expect!(Float).cloned(), self.range_or_operator) >- } >+ Evaluator::Float(eval) => eval(device, expect!(Float).cloned(), self.range_or_operator), > Evaluator::IntRatio(eval) => { > eval(device, expect!(IntRatio).cloned(), self.range_or_operator) >- }, >+ } > Evaluator::Resolution(eval) => { > let computed = expect!(Resolution).map(|specified| { > computed::Context::for_media_query_evaluation(device, quirks_mode, |context| { > specified.to_computed_value(context) > }) > }); > eval(device, computed, self.range_or_operator) > } > Evaluator::Enumerated { evaluator, .. } => { >- evaluator( >- device, >- expect!(Enumerated).cloned(), >- self.range_or_operator, >- ) >- } >- Evaluator::Ident(eval) => { >- eval(device, expect!(Ident).cloned(), self.range_or_operator) >- } >- Evaluator::BoolInteger(eval) => { >- eval(device, expect!(BoolInteger).cloned(), self.range_or_operator) >+ evaluator(device, expect!(Enumerated).cloned(), self.range_or_operator) > } >+ Evaluator::Ident(eval) => eval(device, expect!(Ident).cloned(), self.range_or_operator), >+ Evaluator::BoolInteger(eval) => eval( >+ device, >+ expect!(BoolInteger).cloned(), >+ self.range_or_operator, >+ ), > } > } > } > > /// A value found or expected in a media expression. > /// > /// FIXME(emilio): How should calc() serialize in the Number / Integer / > /// BoolInteger / IntRatio case, as computed or as specified value? >@@ -499,41 +477,31 @@ pub enum MediaExpressionValue { > /// An enumerated value, defined by the variant keyword table in the > /// feature's `mData` member. > Enumerated(KeywordDiscriminant), > /// An identifier. > Ident(Atom), > } > > impl MediaExpressionValue { >- fn to_css<W>( >- &self, >- dest: &mut CssWriter<W>, >- for_expr: &MediaFeatureExpression, >- ) -> fmt::Result >+ fn to_css<W>(&self, dest: &mut CssWriter<W>, for_expr: &MediaFeatureExpression) -> fmt::Result > where > W: fmt::Write, > { > match *self { > MediaExpressionValue::Length(ref l) => l.to_css(dest), > MediaExpressionValue::Integer(v) => v.to_css(dest), > MediaExpressionValue::Float(v) => v.to_css(dest), > MediaExpressionValue::BoolInteger(v) => dest.write_str(if v { "1" } else { "0" }), >- MediaExpressionValue::IntRatio(ratio) => { >- ratio.to_css(dest) >- }, >+ MediaExpressionValue::IntRatio(ratio) => ratio.to_css(dest), > MediaExpressionValue::Resolution(ref r) => r.to_css(dest), > MediaExpressionValue::Ident(ref ident) => serialize_atom_identifier(ident, dest), >- MediaExpressionValue::Enumerated(value) => { >- match for_expr.feature.evaluator { >- Evaluator::Enumerated { serializer, .. } => { >- dest.write_str(&*serializer(value)) >- } >- _ => unreachable!(), >- } >+ MediaExpressionValue::Enumerated(value) => match for_expr.feature.evaluator { >+ Evaluator::Enumerated { serializer, .. } => dest.write_str(&*serializer(value)), >+ _ => unreachable!(), > }, > } > } > > fn parse<'i, 't>( > for_feature: &MediaFeatureDescription, > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -558,20 +526,17 @@ impl MediaExpressionValue { > Evaluator::Float(..) => { > let number = Number::parse(context, input)?; > MediaExpressionValue::Float(number.get()) > } > Evaluator::IntRatio(..) => { > let a = Integer::parse_positive(context, input)?; > input.expect_delim('/')?; > let b = Integer::parse_positive(context, input)?; >- MediaExpressionValue::IntRatio(AspectRatio( >- a.value() as u32, >- b.value() as u32 >- )) >+ MediaExpressionValue::IntRatio(AspectRatio(a.value() as u32, b.value() as u32)) > } > Evaluator::Resolution(..) => { > MediaExpressionValue::Resolution(Resolution::parse(context, input)?) > } > Evaluator::Enumerated { parser, .. } => { > MediaExpressionValue::Enumerated(parser(context, input)?) > } > Evaluator::Ident(..) => { >diff --git a/servo/components/style/media_queries/media_list.rs b/servo/components/style/media_queries/media_list.rs >index f8d15df7257d..7a49b14ae38e 100644 >--- a/servo/components/style/media_queries/media_list.rs >+++ b/servo/components/style/media_queries/media_list.rs >@@ -1,22 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A media query list: > //! > //! https://drafts.csswg.org/mediaqueries/#typedef-media-query-list > >+use super::{Device, MediaQuery, Qualifier}; > use context::QuirksMode; > use cssparser::{Delimiter, Parser}; > use cssparser::{ParserInput, Token}; > use error_reporting::ContextualParseError; > use parser::ParserContext; >-use super::{Device, MediaQuery, Qualifier}; > > /// A type that encapsulates a media query list. > #[css(comma, derive_debug)] > #[derive(Clone, MallocSizeOf, ToCss)] > pub struct MediaList { > /// The list of media queries. > #[css(iterable)] > pub media_queries: Vec<MediaQuery>, >@@ -25,42 +25,41 @@ pub struct MediaList { > impl MediaList { > /// Parse a media query list from CSS. > /// > /// Always returns a media query list. If any invalid media query is > /// found, the media query list is only filled with the equivalent of > /// "not all", see: > /// > /// <https://drafts.csswg.org/mediaqueries/#error-handling> >- pub fn parse( >- context: &ParserContext, >- input: &mut Parser, >- ) -> Self { >+ pub fn parse(context: &ParserContext, input: &mut Parser) -> Self { > if input.is_exhausted() { > return Self::empty(); > } > > let mut media_queries = vec![]; > loop { > let start_position = input.position(); > match input.parse_until_before(Delimiter::Comma, |i| MediaQuery::parse(context, i)) { > Ok(mq) => { > media_queries.push(mq); >- }, >+ } > Err(err) => { > media_queries.push(MediaQuery::never_matching()); > let location = err.location; >- let error = >- ContextualParseError::InvalidMediaRule(input.slice_from(start_position), err); >+ let error = ContextualParseError::InvalidMediaRule( >+ input.slice_from(start_position), >+ err, >+ ); > context.log_css_error(location, error); >- }, >+ } > } > > match input.next() { >- Ok(&Token::Comma) => {}, >+ Ok(&Token::Comma) => {} > Ok(_) => unreachable!(), > Err(_) => break, > } > } > > MediaList { media_queries } > } > >@@ -74,18 +73,20 @@ impl MediaList { > /// Evaluate a whole `MediaList` against `Device`. > pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> bool { > // Check if it is an empty media query list or any queries match. > // https://drafts.csswg.org/mediaqueries-4/#mq-list > self.media_queries.is_empty() || self.media_queries.iter().any(|mq| { > let media_match = mq.media_type.matches(device.media_type()); > > // Check if the media condition match. >- let query_match = media_match && >- mq.condition.as_ref().map_or(true, |c| c.matches(device, quirks_mode)); >+ let query_match = media_match && mq >+ .condition >+ .as_ref() >+ .map_or(true, |c| c.matches(device, quirks_mode)); > > // Apply the logical NOT qualifier to the result > match mq.qualifier { > Some(Qualifier::Not) => !query_match, > _ => query_match, > } > }) > } >@@ -101,17 +102,17 @@ impl MediaList { > /// Returns true if added, false if fail to parse the medium string. > pub fn append_medium(&mut self, context: &ParserContext, new_medium: &str) -> bool { > let mut input = ParserInput::new(new_medium); > let mut parser = Parser::new(&mut input); > let new_query = match MediaQuery::parse(&context, &mut parser) { > Ok(query) => query, > Err(_) => { > return false; >- }, >+ } > }; > // This algorithm doesn't actually matches the current spec, > // but it matches the behavior of Gecko and Edge. > // See https://github.com/w3c/csswg-drafts/issues/697 > self.media_queries.retain(|query| query != &new_query); > self.media_queries.push(new_query); > true > } >@@ -122,15 +123,15 @@ impl MediaList { > /// Returns true if found and deleted, false otherwise. > pub fn delete_medium(&mut self, context: &ParserContext, old_medium: &str) -> bool { > let mut input = ParserInput::new(old_medium); > let mut parser = Parser::new(&mut input); > let old_query = match MediaQuery::parse(context, &mut parser) { > Ok(query) => query, > Err(_) => { > return false; >- }, >+ } > }; > let old_len = self.media_queries.len(); > self.media_queries.retain(|query| query != &old_query); > old_len != self.media_queries.len() > } > } >diff --git a/servo/components/style/media_queries/media_query.rs b/servo/components/style/media_queries/media_query.rs >index 089fc9412b24..f2d11ccb58c6 100644 >--- a/servo/components/style/media_queries/media_query.rs >+++ b/servo/components/style/media_queries/media_query.rs >@@ -1,25 +1,24 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A media query: > //! > //! https://drafts.csswg.org/mediaqueries/#typedef-media-query > >-use Atom; >+use super::media_condition::MediaCondition; > use cssparser::Parser; > use parser::ParserContext; > use std::fmt::{self, Write}; > use str::string_as_ascii_lowercase; > use style_traits::{CssWriter, ParseError, ToCss}; >-use super::media_condition::MediaCondition; > use values::CustomIdent; >- >+use Atom; > > /// <https://drafts.csswg.org/mediaqueries/#mq-prefix> > #[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss)] > pub enum Qualifier { > /// Hide a media query from legacy UAs: > /// <https://drafts.csswg.org/mediaqueries/#mq-only> > Only, > /// Negate a media query: >@@ -85,17 +84,17 @@ impl ToCss for MediaQuery { > // We need to print "all" if there's a qualifier, or there's > // just an empty list of expressions. > // > // Otherwise, we'd serialize media queries like "(min-width: > // 40px)" in "all (min-width: 40px)", which is unexpected. > if self.qualifier.is_some() || self.condition.is_none() { > dest.write_str("all")?; > } >- }, >+ } > MediaQueryType::Concrete(MediaType(ref desc)) => desc.to_css(dest)?, > } > > let condition = match self.condition { > Some(ref c) => c, > None => return Ok(()), > }; > >@@ -120,33 +119,38 @@ impl MediaQuery { > > /// Parse a media query given css input. > /// > /// Returns an error if any of the expressions is unknown. > pub fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { >- let (qualifier, explicit_media_type) = input.try(|input| -> Result<_, ()> { >- let qualifier = input.try(Qualifier::parse).ok(); >- let ident = input.expect_ident().map_err(|_| ())?; >- let media_type = MediaQueryType::parse(&ident)?; >- Ok((qualifier, Some(media_type))) >- }).unwrap_or_default(); >+ let (qualifier, explicit_media_type) = input >+ .try(|input| -> Result<_, ()> { >+ let qualifier = input.try(Qualifier::parse).ok(); >+ let ident = input.expect_ident().map_err(|_| ())?; >+ let media_type = MediaQueryType::parse(&ident)?; >+ Ok((qualifier, Some(media_type))) >+ }).unwrap_or_default(); > > let condition = if explicit_media_type.is_none() { > Some(MediaCondition::parse(context, input)?) > } else if input.try(|i| i.expect_ident_matching("and")).is_ok() { > Some(MediaCondition::parse_disallow_or(context, input)?) > } else { > None > }; > > let media_type = explicit_media_type.unwrap_or(MediaQueryType::All); >- Ok(Self { qualifier, media_type, condition }) >+ Ok(Self { >+ qualifier, >+ media_type, >+ condition, >+ }) > } > } > > /// <http://dev.w3.org/csswg/mediaqueries-3/#media0> > #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)] > pub enum MediaQueryType { > /// A media type that matches every device. > All, >diff --git a/servo/components/style/media_queries/mod.rs b/servo/components/style/media_queries/mod.rs >index b59ec32443dc..93a5abf3b011 100644 >--- a/servo/components/style/media_queries/mod.rs >+++ b/servo/components/style/media_queries/mod.rs >@@ -9,16 +9,16 @@ > mod media_condition; > mod media_list; > mod media_query; > #[macro_use] > pub mod media_feature; > pub mod media_feature_expression; > > pub use self::media_condition::MediaCondition; >+pub use self::media_feature_expression::MediaFeatureExpression; > pub use self::media_list::MediaList; > pub use self::media_query::{MediaQuery, MediaQueryType, MediaType, Qualifier}; >-pub use self::media_feature_expression::MediaFeatureExpression; > >-#[cfg(feature = "servo")] >-pub use servo::media_queries::Device; > #[cfg(feature = "gecko")] > pub use gecko::media_queries::Device; >+#[cfg(feature = "servo")] >+pub use servo::media_queries::Device; >diff --git a/servo/components/style/parser.rs b/servo/components/style/parser.rs >index a4b7d8162035..e0476dadccbc 100644 >--- a/servo/components/style/parser.rs >+++ b/servo/components/style/parser.rs >@@ -123,21 +123,17 @@ impl<'a> ParserContext<'a> { > > /// Get the rule type, which assumes that one is available. > pub fn rule_type(&self) -> CssRuleType { > self.rule_type > .expect("Rule type expected, but none was found.") > } > > /// Record a CSS parse error with this contextâs error reporting. >- pub fn log_css_error( >- &self, >- location: SourceLocation, >- error: ContextualParseError, >- ) { >+ pub fn log_css_error(&self, location: SourceLocation, error: ContextualParseError) { > let error_reporter = match self.error_reporter { > Some(r) => r, > None => return, > }; > > error_reporter.report_error(self.url_data, location, error) > } > >diff --git a/servo/components/style/rule_cache.rs b/servo/components/style/rule_cache.rs >index 5e386d711cb1..ed1cd70b5556 100644 >--- a/servo/components/style/rule_cache.rs >+++ b/servo/components/style/rule_cache.rs >@@ -100,20 +100,20 @@ impl RuleCache { > match node.style_source() { > Some(s) => match s.as_declarations() { > Some(decls) => { > let cascade_level = node.cascade_level(); > let decls = decls.read_with(cascade_level.guard(guards)); > if decls.contains_any_reset() { > break; > } >- }, >+ } > None => break, > }, >- None => {}, >+ None => {} > } > rule_node = node.parent(); > } > rule_node > } > > /// Finds a node in the properties matched cache. > /// >diff --git a/servo/components/style/rule_tree/mod.rs b/servo/components/style/rule_tree/mod.rs >index 5414b254aaec..53f9b0c15c14 100644 >--- a/servo/components/style/rule_tree/mod.rs >+++ b/servo/components/style/rule_tree/mod.rs >@@ -235,35 +235,35 @@ impl RuleTree { > if any_important { > found_important = true; > match level { > InnerShadowNormal => { > debug_assert!( > shadow_cascade_order >= last_cascade_order, > "Not really ordered" > ); >- if shadow_cascade_order > last_cascade_order && >- !important_inner_shadow.last().unwrap().is_empty() >+ if shadow_cascade_order > last_cascade_order >+ && !important_inner_shadow.last().unwrap().is_empty() > { > last_cascade_order = shadow_cascade_order; > important_inner_shadow.push(SmallVec::new()); > } > important_inner_shadow > .last_mut() > .unwrap() > .push(source.clone()) >- }, >+ } > SameTreeAuthorNormal => important_same_tree.push(source.clone()), > UANormal => important_ua.push(source.clone()), > UserNormal => important_user.push(source.clone()), > StyleAttributeNormal => { > debug_assert!(important_style_attr.is_none()); > important_style_attr = Some(source.clone()); >- }, >- _ => {}, >+ } >+ _ => {} > }; > } > > // We don't optimize out empty rules, even though we could. > // > // Inspector relies on every rule being inserted in the normal level > // at least once, in order to return the rules with the correct > // specificity order. >@@ -483,17 +483,18 @@ impl RuleTree { > > /// Returns new rule node without rules from declarative animations. > pub fn remove_animation_rules(&self, path: &StrongRuleNode) -> StrongRuleNode { > // Return a clone if there are no animation rules. > if !path.has_animation_or_transition_rules() { > return path.clone(); > } > >- let iter = path.self_and_ancestors() >+ let iter = path >+ .self_and_ancestors() > .take_while(|node| node.cascade_level() >= CascadeLevel::SMILOverride); > let mut last = path; > let mut children = SmallVec::<[_; 10]>::new(); > for node in iter { > if !node.cascade_level().is_animation() { > children.push(( > node.get().source.as_ref().unwrap().clone(), > node.cascade_level(), >@@ -605,47 +606,47 @@ impl CascadeLevel { > pub unsafe fn from_byte(byte: u8) -> Self { > debug_assert!(byte <= CascadeLevel::Transitions as u8); > mem::transmute(byte) > } > > /// Select a lock guard for this level > pub fn guard<'a>(&self, guards: &'a StylesheetGuards<'a>) -> &'a SharedRwLockReadGuard<'a> { > match *self { >- CascadeLevel::UANormal | >- CascadeLevel::UserNormal | >- CascadeLevel::UserImportant | >- CascadeLevel::UAImportant => guards.ua_or_user, >+ CascadeLevel::UANormal >+ | CascadeLevel::UserNormal >+ | CascadeLevel::UserImportant >+ | CascadeLevel::UAImportant => guards.ua_or_user, > _ => guards.author, > } > } > > /// Returns whether this cascade level is unique per element, in which case > /// we can replace the path in the cascade without fear. > pub fn is_unique_per_element(&self) -> bool { > match *self { >- CascadeLevel::Transitions | >- CascadeLevel::Animations | >- CascadeLevel::SMILOverride | >- CascadeLevel::StyleAttributeNormal | >- CascadeLevel::StyleAttributeImportant => true, >+ CascadeLevel::Transitions >+ | CascadeLevel::Animations >+ | CascadeLevel::SMILOverride >+ | CascadeLevel::StyleAttributeNormal >+ | CascadeLevel::StyleAttributeImportant => true, > _ => false, > } > } > > /// Returns whether this cascade level represents important rules of some > /// sort. > #[inline] > pub fn is_important(&self) -> bool { > match *self { >- CascadeLevel::SameTreeAuthorImportant | >- CascadeLevel::InnerShadowImportant | >- CascadeLevel::StyleAttributeImportant | >- CascadeLevel::UserImportant | >- CascadeLevel::UAImportant => true, >+ CascadeLevel::SameTreeAuthorImportant >+ | CascadeLevel::InnerShadowImportant >+ | CascadeLevel::StyleAttributeImportant >+ | CascadeLevel::UserImportant >+ | CascadeLevel::UAImportant => true, > _ => false, > } > } > > /// Returns the importance relevant for this rule. Pretty similar to > /// `is_important`. > #[inline] > pub fn importance(&self) -> Importance { >@@ -657,17 +658,17 @@ impl CascadeLevel { > } > > /// Returns whether this cascade level represents an animation rules. > #[inline] > pub fn is_animation(&self) -> bool { > match *self { > CascadeLevel::SMILOverride | CascadeLevel::Animations | CascadeLevel::Transitions => { > true >- }, >+ } > _ => false, > } > } > } > > // The root node never has siblings, but needs a free count. We use the same > // storage for both to save memory. > struct PrevSiblingOrFreeCount(AtomicPtr<RuleNode>); >@@ -724,19 +725,19 @@ pub struct RuleNode { > > unsafe impl Sync for RuleTree {} > unsafe impl Send for RuleTree {} > > // On Gecko builds, hook into the leak checking machinery. > #[cfg(feature = "gecko")] > #[cfg(debug_assertions)] > mod gecko_leak_checking { >+ use super::RuleNode; > use std::mem::size_of; > use std::os::raw::{c_char, c_void}; >- use super::RuleNode; > > extern "C" { > pub fn NS_LogCtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32); > pub fn NS_LogDtor(aPtr: *const c_void, aTypeName: *const c_char, aSize: u32); > } > > static NAME: &'static [u8] = b"RuleNode\0"; > >@@ -1101,18 +1102,18 @@ impl StrongRuleNode { > > // FIXME(#14213): Apparently the layout data can be gone from script. > // > // That's... suspicious, but it's fine if it happens for the rule tree > // case, so just don't crash in the case we're doing the final GC in > // script. > > debug_assert!( >- !thread_state::get().is_worker() && >- (thread_state::get().is_layout() || thread_state::get().is_script()) >+ !thread_state::get().is_worker() >+ && (thread_state::get().is_layout() || thread_state::get().is_script()) > ); > > let current = me.next_free.load(Ordering::Relaxed); > if current == FREE_LIST_SENTINEL { > return None; > } > > debug_assert!( >@@ -1345,63 +1346,63 @@ impl StrongRuleNode { > match declaration.id() { > PropertyDeclarationId::Longhand(id) => Some((id, declaration)), > _ => None, > } > }); > > match node.cascade_level() { > // Non-author rules: >- CascadeLevel::UANormal | >- CascadeLevel::UAImportant | >- CascadeLevel::UserNormal | >- CascadeLevel::UserImportant => { >+ CascadeLevel::UANormal >+ | CascadeLevel::UAImportant >+ | CascadeLevel::UserNormal >+ | CascadeLevel::UserImportant => { > for (id, declaration) in longhands { > if properties.contains(id) { > // This property was set by a non-author rule. > // Stop looking for it in this element's rule > // nodes. > properties.remove(id); > > // However, if it is inherited, then it might be > // inherited from an author rule from an > // ancestor element's rule nodes. >- if declaration.get_css_wide_keyword() == >- Some(CSSWideKeyword::Inherit) >+ if declaration.get_css_wide_keyword() >+ == Some(CSSWideKeyword::Inherit) > { > have_explicit_ua_inherit = true; > inherited_properties.insert(id); > } > } > } >- }, >+ } > // Author rules: >- CascadeLevel::PresHints | >- CascadeLevel::SameTreeAuthorNormal | >- CascadeLevel::InnerShadowNormal | >- CascadeLevel::StyleAttributeNormal | >- CascadeLevel::SMILOverride | >- CascadeLevel::Animations | >- CascadeLevel::SameTreeAuthorImportant | >- CascadeLevel::InnerShadowImportant | >- CascadeLevel::StyleAttributeImportant | >- CascadeLevel::Transitions => { >+ CascadeLevel::PresHints >+ | CascadeLevel::SameTreeAuthorNormal >+ | CascadeLevel::InnerShadowNormal >+ | CascadeLevel::StyleAttributeNormal >+ | CascadeLevel::SMILOverride >+ | CascadeLevel::Animations >+ | CascadeLevel::SameTreeAuthorImportant >+ | CascadeLevel::InnerShadowImportant >+ | CascadeLevel::StyleAttributeImportant >+ | CascadeLevel::Transitions => { > for (id, declaration) in longhands { > if properties.contains(id) { > if !author_colors_allowed { > if let PropertyDeclaration::BackgroundColor(ref color) = > *declaration > { > return *color == Color::transparent(); > } > } > return true; > } > } >- }, >+ } > } > } > > if !have_explicit_ua_inherit { > break; > } > > // Continue to the parent element and search for the inherited properties. >@@ -1447,17 +1448,18 @@ impl StrongRuleNode { > // We want to iterate over cascade levels that override the animations > // level, i.e. !important levels and the transitions level. > // > // However, we actually want to skip the transitions level because > // although it is higher in the cascade than animations, when both > // transitions and animations are present for a given element and > // property, transitions are suppressed so that they don't actually > // override animations. >- let iter = self.self_and_ancestors() >+ let iter = self >+ .self_and_ancestors() > .skip_while(|node| node.cascade_level() == CascadeLevel::Transitions) > .take_while(|node| node.cascade_level() > CascadeLevel::Animations); > let mut result = (LonghandIdSet::new(), false); > for node in iter { > let style = node.style_source().unwrap(); > for (decl, important) in style > .read(node.cascade_level().guard(guards)) > .declaration_importance_iter() >@@ -1554,18 +1556,18 @@ impl Drop for StrongRuleNode { > // here to avoid leaking anything. We use the GC machinery, rather > // than just dropping directly, so that we benefit from the iterative > // destruction and don't trigger unbounded recursion during drop. See > // [1] and the associated crashtest. > // > // [1] https://bugzilla.mozilla.org/show_bug.cgi?id=439184 > if old_head.is_null() { > debug_assert!( >- !thread_state::get().is_worker() && >- (thread_state::get().is_layout() || thread_state::get().is_script()) >+ !thread_state::get().is_worker() >+ && (thread_state::get().is_layout() || thread_state::get().is_script()) > ); > // Add the node as the sole entry in the free list. > debug_assert!(node.next_free.load(Ordering::Relaxed).is_null()); > node.next_free.store(FREE_LIST_SENTINEL, Ordering::Relaxed); > free_list.store(node as *const _ as *mut _, Ordering::Relaxed); > > // Invoke the GC. > // >@@ -1609,17 +1611,17 @@ impl Drop for StrongRuleNode { > FREE_LIST_LOCKED, > Ordering::Acquire, > Ordering::Relaxed, > ) { > Ok(..) => { > if old_head != FREE_LIST_LOCKED { > break; > } >- }, >+ } > Err(new) => old_head = new, > } > } > > // If other thread has raced with use while using the same rule node, > // just store the old head again, we're done. > // > // Note that we can use relaxed operations for loading since we're >diff --git a/servo/components/style/selector_map.rs b/servo/components/style/selector_map.rs >index 3ab78ce2d87b..f3476e497381 100644 >--- a/servo/components/style/selector_map.rs >+++ b/servo/components/style/selector_map.rs >@@ -1,31 +1,31 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A data structure to efficiently index structs containing selectors by local > //! name, ids and hash. > >-use {Atom, LocalName, Namespace, WeakAtom}; > use applicable_declarations::ApplicableDeclarationList; > use context::QuirksMode; > use dom::TElement; > use fallible::FallibleVec; >-use hash::{HashMap, HashSet}; > use hash::map as hash_map; >+use hash::{HashMap, HashSet}; > use hashglobe::FailedAllocationError; > use precomputed_hash::PrecomputedHash; > use rule_tree::{CascadeLevel, ShadowCascadeOrder}; > use selector_parser::SelectorImpl; > use selectors::matching::{matches_selector, ElementSelectorFlags, MatchingContext}; > use selectors::parser::{Combinator, Component, SelectorIter}; > use smallvec::SmallVec; > use std::hash::{BuildHasherDefault, Hash, Hasher}; > use stylist::Rule; >+use {Atom, LocalName, Namespace, WeakAtom}; > > /// A hasher implementation that doesn't hash anything, because it expects its > /// input to be a suitable u32 hash. > pub struct PrecomputedHasher { > hash: Option<u32>, > } > > impl Default for PrecomputedHasher { >@@ -282,17 +282,19 @@ impl SelectorMap<Rule> { > if matches_selector( > &rule.selector, > 0, > Some(&rule.hashes), > &element, > context, > flags_setter, > ) { >- matching_rules.push(rule.to_applicable_declaration_block(cascade_level, shadow_cascade_order)); >+ matching_rules.push( >+ rule.to_applicable_declaration_block(cascade_level, shadow_cascade_order), >+ ); > } > } > } > } > > impl<T: SelectorMapEntry> SelectorMap<T> { > /// Inserts into the correct hash, trying id, class, localname and > /// namespace. >@@ -300,20 +302,22 @@ impl<T: SelectorMapEntry> SelectorMap<T> { > &mut self, > entry: T, > quirks_mode: QuirksMode, > ) -> Result<(), FailedAllocationError> { > self.count += 1; > > let vector = match find_bucket(entry.selector()) { > Bucket::Root => &mut self.root, >- Bucket::ID(id) => self.id_hash >+ Bucket::ID(id) => self >+ .id_hash > .try_entry(id.clone(), quirks_mode)? > .or_insert_with(SmallVec::new), >- Bucket::Class(class) => self.class_hash >+ Bucket::Class(class) => self >+ .class_hash > .try_entry(class.clone(), quirks_mode)? > .or_insert_with(SmallVec::new), > Bucket::LocalName { name, lower_name } => { > // If the local name in the selector isn't lowercase, insert it > // into the rule hash twice. This means that, during lookup, we > // can always find the rules based on the local name of the > // element, regardless of whether it's an html element in an > // html document (in which case we match against lower_name) or >@@ -327,18 +331,19 @@ impl<T: SelectorMapEntry> SelectorMap<T> { > self.local_name_hash > .try_entry(lower_name.clone())? > .or_insert_with(SmallVec::new) > .try_push(entry.clone())?; > } > self.local_name_hash > .try_entry(name.clone())? > .or_insert_with(SmallVec::new) >- }, >- Bucket::Namespace(url) => self.namespace_hash >+ } >+ Bucket::Namespace(url) => self >+ .namespace_hash > .try_entry(url.clone())? > .or_insert_with(SmallVec::new), > Bucket::Universal => &mut self.other, > }; > > vector.try_push(entry) > } > >@@ -485,18 +490,19 @@ fn specific_bucket_for<'a>(component: &'a Component<SelectorImpl>) -> Bucket<'a> > match *component { > Component::Root => Bucket::Root, > Component::ID(ref id) => Bucket::ID(id), > Component::Class(ref class) => Bucket::Class(class), > Component::LocalName(ref selector) => Bucket::LocalName { > name: &selector.name, > lower_name: &selector.lower_name, > }, >- Component::Namespace(_, ref url) | >- Component::DefaultNamespace(ref url) => Bucket::Namespace(url), >+ Component::Namespace(_, ref url) | Component::DefaultNamespace(ref url) => { >+ Bucket::Namespace(url) >+ } > // ::slotted(..) isn't a normal pseudo-element, so we can insert it on > // the rule hash normally without much problem. For example, in a > // selector like: > // > // div::slotted(span)::before > // > // It looks like: > // >@@ -534,28 +540,28 @@ fn find_bucket<'a>(mut iter: SelectorIter<'a, SelectorImpl>) -> Bucket<'a> { > Bucket::Root => return new_bucket, > Bucket::ID(..) => { > current_bucket = new_bucket; > } > Bucket::Class(..) => { > if !matches!(current_bucket, Bucket::ID(..)) { > current_bucket = new_bucket; > } >- }, >+ } > Bucket::LocalName { .. } => { > if matches!(current_bucket, Bucket::Universal | Bucket::Namespace(..)) { > current_bucket = new_bucket; > } >- }, >+ } > Bucket::Namespace(..) => { > if matches!(current_bucket, Bucket::Universal) { > current_bucket = new_bucket; > } > } >- Bucket::Universal => {}, >+ Bucket::Universal => {} > } > } > > // Effectively, pseudo-elements are ignored, given only state > // pseudo-classes may appear before them. > if iter.next_sequence() != Some(Combinator::PseudoElement) { > break; > } >diff --git a/servo/components/style/servo/media_queries.rs b/servo/components/style/servo/media_queries.rs >index ba31cfcaf4b3..ef7c70bae570 100644 >--- a/servo/components/style/servo/media_queries.rs >+++ b/servo/components/style/servo/media_queries.rs >@@ -9,21 +9,21 @@ use context::QuirksMode; > use cssparser::{Parser, RGBA}; > use euclid::{Size2D, TypedScale, TypedSize2D}; > use media_queries::MediaType; > use parser::ParserContext; > use properties::ComputedValues; > use selectors::parser::SelectorParseErrorKind; > use std::fmt::{self, Write}; > use std::sync::atomic::{AtomicBool, AtomicIsize, Ordering}; >-use style_traits::{CSSPixel, CssWriter, DevicePixel, ParseError, ToCss}; > use style_traits::viewport::ViewportConstraints; >-use values::{specified, KeyframesName}; >-use values::computed::{self, ToComputedValue}; >+use style_traits::{CSSPixel, CssWriter, DevicePixel, ParseError, ToCss}; > use values::computed::font::FontSize; >+use values::computed::{self, ToComputedValue}; >+use values::{specified, KeyframesName}; > > /// A device is a structure that represents the current media a given document > /// is displayed in. > /// > /// This is the struct against which media queries are evaluated. > #[derive(Debug, MallocSizeOf)] > pub struct Device { > /// The current media type used by de device. >@@ -187,19 +187,17 @@ impl MediaFeatureExpression { > /// ``` > /// > /// Only supports width ranges for now. > pub fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > input.expect_parenthesis_block()?; >- input.parse_nested_block(|input| { >- Self::parse_in_parenthesis_block(context, input) >- }) >+ input.parse_nested_block(|input| Self::parse_in_parenthesis_block(context, input)) > } > > /// Parse a media range expression where we've already consumed the > /// parenthesis. > pub fn parse_in_parenthesis_block<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { >@@ -227,17 +225,17 @@ impl MediaFeatureExpression { > let value = viewport_size.width; > match self.0 { > ExpressionKind::Width(ref range) => { > match range.to_computed_range(device, quirks_mode) { > Range::Min(ref width) => value >= *width, > Range::Max(ref width) => value <= *width, > Range::Eq(ref width) => value == *width, > } >- }, >+ } > } > } > } > > impl ToCss for MediaFeatureExpression { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, >diff --git a/servo/components/style/servo/restyle_damage.rs b/servo/components/style/servo/restyle_damage.rs >index 5cde20c9658f..ff34df0aedce 100644 >--- a/servo/components/style/servo/restyle_damage.rs >+++ b/servo/components/style/servo/restyle_damage.rs >@@ -75,41 +75,46 @@ impl ServoRestyleDamage { > } > > /// Returns a bitmask that represents a flow that needs to be rebuilt and > /// reflowed. > /// > /// FIXME(bholley): Do we ever actually need this? Shouldn't > /// RECONSTRUCT_FLOW imply everything else? > pub fn rebuild_and_reflow() -> ServoRestyleDamage { >- ServoRestyleDamage::REPAINT | ServoRestyleDamage::REPOSITION | >- ServoRestyleDamage::STORE_OVERFLOW | ServoRestyleDamage::BUBBLE_ISIZES | >- ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW | >- ServoRestyleDamage::RECONSTRUCT_FLOW >+ ServoRestyleDamage::REPAINT >+ | ServoRestyleDamage::REPOSITION >+ | ServoRestyleDamage::STORE_OVERFLOW >+ | ServoRestyleDamage::BUBBLE_ISIZES >+ | ServoRestyleDamage::REFLOW_OUT_OF_FLOW >+ | ServoRestyleDamage::REFLOW >+ | ServoRestyleDamage::RECONSTRUCT_FLOW > } > > /// Returns a bitmask indicating that the frame needs to be reconstructed. > pub fn reconstruct() -> ServoRestyleDamage { > ServoRestyleDamage::RECONSTRUCT_FLOW > } > > /// Supposing a flow has the given `position` property and this damage, > /// returns the damage that we should add to the *parent* of this flow. > pub fn damage_for_parent(self, child_is_absolutely_positioned: bool) -> ServoRestyleDamage { > if child_is_absolutely_positioned { >- self & (ServoRestyleDamage::REPAINT | ServoRestyleDamage::REPOSITION | >- ServoRestyleDamage::STORE_OVERFLOW | >- ServoRestyleDamage::REFLOW_OUT_OF_FLOW | >- ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) >+ self & (ServoRestyleDamage::REPAINT >+ | ServoRestyleDamage::REPOSITION >+ | ServoRestyleDamage::STORE_OVERFLOW >+ | ServoRestyleDamage::REFLOW_OUT_OF_FLOW >+ | ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) > } else { >- self & (ServoRestyleDamage::REPAINT | ServoRestyleDamage::REPOSITION | >- ServoRestyleDamage::STORE_OVERFLOW | >- ServoRestyleDamage::REFLOW | >- ServoRestyleDamage::REFLOW_OUT_OF_FLOW | >- ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) >+ self & (ServoRestyleDamage::REPAINT >+ | ServoRestyleDamage::REPOSITION >+ | ServoRestyleDamage::STORE_OVERFLOW >+ | ServoRestyleDamage::REFLOW >+ | ServoRestyleDamage::REFLOW_OUT_OF_FLOW >+ | ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) > } > } > > /// Supposing the *parent* of a flow with the given `position` property has > /// this damage, returns the damage that we should add to this flow. > pub fn damage_for_child( > self, > parent_is_absolutely_positioned: bool, >@@ -119,31 +124,32 @@ impl ServoRestyleDamage { > parent_is_absolutely_positioned, > child_is_absolutely_positioned, > ) { > (false, true) => { > // Absolute children are out-of-flow and therefore insulated from changes. > // > // FIXME(pcwalton): Au contraire, if the containing block dimensions change! > self & (ServoRestyleDamage::REPAINT | ServoRestyleDamage::REPOSITION) >- }, >+ } > (true, false) => { > // Changing the position of an absolutely-positioned block requires us to reflow > // its kids. > if self.contains(ServoRestyleDamage::REFLOW_OUT_OF_FLOW) { > self | ServoRestyleDamage::REFLOW > } else { > self > } >- }, >+ } > _ => { > // TODO(pcwalton): Take floatedness into account. >- self & (ServoRestyleDamage::REPAINT | ServoRestyleDamage::REPOSITION | >- ServoRestyleDamage::REFLOW) >- }, >+ self & (ServoRestyleDamage::REPAINT >+ | ServoRestyleDamage::REPOSITION >+ | ServoRestyleDamage::REFLOW) >+ } > } > } > } > > impl Default for ServoRestyleDamage { > fn default() -> Self { > Self::empty() > } >@@ -200,56 +206,56 @@ fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> ServoRestyleDam > ServoRestyleDamage::REPAINT, > ServoRestyleDamage::REPOSITION, > ServoRestyleDamage::STORE_OVERFLOW, > ServoRestyleDamage::BUBBLE_ISIZES, > ServoRestyleDamage::REFLOW_OUT_OF_FLOW, > ServoRestyleDamage::REFLOW, > ServoRestyleDamage::RECONSTRUCT_FLOW > ] >- ) || >- (new.get_box().display == Display::Inline && >- restyle_damage_rebuild_and_reflow_inline!( >- old, >- new, >- damage, >- [ >- ServoRestyleDamage::REPAINT, >- ServoRestyleDamage::REPOSITION, >- ServoRestyleDamage::STORE_OVERFLOW, >- ServoRestyleDamage::BUBBLE_ISIZES, >- ServoRestyleDamage::REFLOW_OUT_OF_FLOW, >- ServoRestyleDamage::REFLOW, >- ServoRestyleDamage::RECONSTRUCT_FLOW >- ] >- )) || >- restyle_damage_reflow!( >+ ) || (new.get_box().display == Display::Inline >+ && restyle_damage_rebuild_and_reflow_inline!( >+ old, >+ new, >+ damage, >+ [ >+ ServoRestyleDamage::REPAINT, >+ ServoRestyleDamage::REPOSITION, >+ ServoRestyleDamage::STORE_OVERFLOW, >+ ServoRestyleDamage::BUBBLE_ISIZES, >+ ServoRestyleDamage::REFLOW_OUT_OF_FLOW, >+ ServoRestyleDamage::REFLOW, >+ ServoRestyleDamage::RECONSTRUCT_FLOW >+ ] >+ )) >+ || restyle_damage_reflow!( > old, > new, > damage, > [ > ServoRestyleDamage::REPAINT, > ServoRestyleDamage::REPOSITION, > ServoRestyleDamage::STORE_OVERFLOW, > ServoRestyleDamage::BUBBLE_ISIZES, > ServoRestyleDamage::REFLOW_OUT_OF_FLOW, > ServoRestyleDamage::REFLOW > ] >- ) || >- restyle_damage_reflow_out_of_flow!( >+ ) >+ || restyle_damage_reflow_out_of_flow!( > old, > new, > damage, > [ > ServoRestyleDamage::REPAINT, > ServoRestyleDamage::REPOSITION, > ServoRestyleDamage::STORE_OVERFLOW, > ServoRestyleDamage::REFLOW_OUT_OF_FLOW > ] >- ) || restyle_damage_repaint!(old, new, damage, [ServoRestyleDamage::REPAINT]); >+ ) >+ || restyle_damage_repaint!(old, new, damage, [ServoRestyleDamage::REPAINT]); > > // Paint worklets may depend on custom properties, > // so if they have changed we should repaint. > if old.custom_properties() != new.custom_properties() { > damage.insert(ServoRestyleDamage::REPAINT); > } > > // If the layer requirements of this flow have changed due to the value >diff --git a/servo/components/style/servo/selector_parser.rs b/servo/components/style/servo/selector_parser.rs >index 2083539f51b3..5762d4b54e33 100644 >--- a/servo/components/style/servo/selector_parser.rs >+++ b/servo/components/style/servo/selector_parser.rs >@@ -1,34 +1,34 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #![deny(missing_docs)] > > //! Servo's selector parser. > >-use {Atom, CaseSensitivityExt, LocalName, Namespace, Prefix}; > use attr::{AttrIdentifier, AttrValue}; > use cssparser::{serialize_identifier, CowRcStr, Parser as CssParser, SourceLocation, ToCss}; > use dom::{OpaqueNode, TElement, TNode}; > use element_state::{DocumentState, ElementState}; > use fxhash::FxHashMap; > use invalidation::element::document_state::InvalidationMatchingData; > use invalidation::element::element_wrapper::ElementSnapshot; >-use properties::{ComputedValues, PropertyFlags}; > use properties::longhands::display::computed_value::T as Display; >+use properties::{ComputedValues, PropertyFlags}; > use selector_parser::{AttrValue as SelectorAttrValue, PseudoElementCascadeType, SelectorParser}; > use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint}; > use selectors::parser::{SelectorParseErrorKind, Visit}; > use selectors::visitor::SelectorVisitor; > use std::fmt; > use std::mem; > use std::ops::{Deref, DerefMut}; > use style_traits::{ParseError, StyleParseErrorKind}; >+use {Atom, CaseSensitivityExt, LocalName, Namespace, Prefix}; > > /// A pseudo-element, both public and private. > /// > /// NB: If you add to this list, be sure to update `each_simple_pseudo_element` too. > #[derive(Clone, Debug, Eq, Hash, PartialEq)] > #[cfg_attr(feature = "servo", derive(MallocSizeOf))] > #[allow(missing_docs)] > #[repr(usize)] >@@ -194,29 +194,29 @@ impl PseudoElement { > /// For more info on cascade types, see docs/components/style.md > /// > /// Note: Keep this in sync with EAGER_PSEUDO_COUNT. > #[inline] > pub fn cascade_type(&self) -> PseudoElementCascadeType { > match *self { > PseudoElement::After | PseudoElement::Before | PseudoElement::Selection => { > PseudoElementCascadeType::Eager >- }, >+ } > PseudoElement::DetailsSummary => PseudoElementCascadeType::Lazy, >- PseudoElement::DetailsContent | >- PseudoElement::ServoText | >- PseudoElement::ServoInputText | >- PseudoElement::ServoTableWrapper | >- PseudoElement::ServoAnonymousTableWrapper | >- PseudoElement::ServoAnonymousTable | >- PseudoElement::ServoAnonymousTableRow | >- PseudoElement::ServoAnonymousTableCell | >- PseudoElement::ServoAnonymousBlock | >- PseudoElement::ServoInlineBlockWrapper | >- PseudoElement::ServoInlineAbsolute => PseudoElementCascadeType::Precomputed, >+ PseudoElement::DetailsContent >+ | PseudoElement::ServoText >+ | PseudoElement::ServoInputText >+ | PseudoElement::ServoTableWrapper >+ | PseudoElement::ServoAnonymousTableWrapper >+ | PseudoElement::ServoAnonymousTable >+ | PseudoElement::ServoAnonymousTableRow >+ | PseudoElement::ServoAnonymousTableCell >+ | PseudoElement::ServoAnonymousBlock >+ | PseudoElement::ServoInlineBlockWrapper >+ | PseudoElement::ServoInlineAbsolute => PseudoElementCascadeType::Precomputed, > } > } > > /// For most (but not all) anon-boxes, we inherit all values from the > /// parent, this is the hook in the style system to allow this. > /// > /// FIXME(emilio): It's likely that this is broken in a variety of > /// situations, and what it really wants is just inherit some reset >@@ -328,23 +328,23 @@ impl ToCss for NonTSPseudoClass { > W: fmt::Write, > { > use self::NonTSPseudoClass::*; > match *self { > Lang(ref lang) => { > dest.write_str(":lang(")?; > serialize_identifier(lang, dest)?; > return dest.write_str(")"); >- }, >+ } > ServoCaseSensitiveTypeAttr(ref value) => { > dest.write_str(":-servo-case-sensitive-type-attr(")?; > serialize_identifier(value, dest)?; > return dest.write_str(")"); >- }, >- _ => {}, >+ } >+ _ => {} > } > > dest.write_str(match *self { > Active => ":active", > AnyLink => ":any-link", > Checked => ":checked", > Disabled => ":disabled", > Enabled => ":enabled", >@@ -374,37 +374,37 @@ impl Visit for NonTSPseudoClass { > true > } > } > > impl NonTSPseudoClass { > /// Gets a given state flag for this pseudo-class. This is used to do > /// selector matching, and it's set from the DOM. > pub fn state_flag(&self) -> ElementState { >+ use self::NonTSPseudoClass::*; > use element_state::ElementState; >- use self::NonTSPseudoClass::*; > match *self { > Active => ElementState::IN_ACTIVE_STATE, > Focus => ElementState::IN_FOCUS_STATE, > Fullscreen => ElementState::IN_FULLSCREEN_STATE, > Hover => ElementState::IN_HOVER_STATE, > Enabled => ElementState::IN_ENABLED_STATE, > Disabled => ElementState::IN_DISABLED_STATE, > Checked => ElementState::IN_CHECKED_STATE, > Indeterminate => ElementState::IN_INDETERMINATE_STATE, > ReadOnly | ReadWrite => ElementState::IN_READ_WRITE_STATE, > PlaceholderShown => ElementState::IN_PLACEHOLDER_SHOWN_STATE, > Target => ElementState::IN_TARGET_STATE, > >- AnyLink | >- Lang(_) | >- Link | >- Visited | >- ServoNonZeroBorder | >- ServoCaseSensitiveTypeAttr(_) => ElementState::empty(), >+ AnyLink >+ | Lang(_) >+ | Link >+ | Visited >+ | ServoNonZeroBorder >+ | ServoCaseSensitiveTypeAttr(_) => ElementState::empty(), > } > } > > /// Get the document state flag associated with a pseudo-class, if any. > pub fn document_state_flag(&self) -> DocumentState { > DocumentState::empty() > } > >@@ -757,38 +757,39 @@ impl ServoElementSnapshot { > /// selectors::Element::attr_matches > pub fn attr_matches( > &self, > ns: &NamespaceConstraint<&Namespace>, > local_name: &LocalName, > operation: &AttrSelectorOperation<&String>, > ) -> bool { > match *ns { >- NamespaceConstraint::Specific(ref ns) => self.get_attr(ns, local_name) >+ NamespaceConstraint::Specific(ref ns) => self >+ .get_attr(ns, local_name) > .map_or(false, |value| value.eval_selector(operation)), > NamespaceConstraint::Any => { > self.any_attr_ignore_ns(local_name, |value| value.eval_selector(operation)) >- }, >+ } > } > } > } > > /// Returns whether the language is matched, as defined by > /// [RFC 4647](https://tools.ietf.org/html/rfc4647#section-3.3.2). > pub fn extended_filtering(tag: &str, range: &str) -> bool { > range.split(',').any(|lang_range| { > // step 1 > let mut range_subtags = lang_range.split('\x2d'); > let mut tag_subtags = tag.split('\x2d'); > > // step 2 > // Note: [Level-4 spec](https://drafts.csswg.org/selectors/#lang-pseudo) check for wild card > if let (Some(range_subtag), Some(tag_subtag)) = (range_subtags.next(), tag_subtags.next()) { >- if !(range_subtag.eq_ignore_ascii_case(tag_subtag) || >- range_subtag.eq_ignore_ascii_case("*")) >+ if !(range_subtag.eq_ignore_ascii_case(tag_subtag) >+ || range_subtag.eq_ignore_ascii_case("*")) > { > return false; > } > } > > let mut current_tag_subtag = tag_subtags.next(); > > // step 3 >@@ -808,19 +809,19 @@ pub fn extended_filtering(tag: &str, range: &str) -> bool { > if tag_subtag.len() == 1 { > return false; > } > // else step 3e - continue with loop > current_tag_subtag = tag_subtags.next(); > if current_tag_subtag.is_none() { > return false; > } >- }, >+ } > // step 3b > None => { > return false; >- }, >+ } > } > } > // step 4 > true > }) > } >diff --git a/servo/components/style/servo/url.rs b/servo/components/style/servo/url.rs >index b4821f21e669..4c5275d45550 100644 >--- a/servo/components/style/servo/url.rs >+++ b/servo/components/style/servo/url.rs >@@ -152,17 +152,17 @@ impl ToComputedValue for SpecifiedUrl { > // but still return it as a ComputedUrl::Invalid > fn to_computed_value(&self, _: &Context) -> Self::ComputedValue { > match self.resolved { > Some(ref url) => ComputedUrl::Valid(url.clone()), > None => match self.original { > Some(ref url) => ComputedUrl::Invalid(url.clone()), > None => { > unreachable!("Found specified url with neither resolved or original URI!"); >- }, >+ } > }, > } > } > > fn from_computed_value(computed: &ComputedUrl) -> Self { > match *computed { > ComputedUrl::Valid(ref url) => SpecifiedUrl { > original: None, >diff --git a/servo/components/style/sharing/mod.rs b/servo/components/style/sharing/mod.rs >index d6148d16b49c..052764a6010e 100644 >--- a/servo/components/style/sharing/mod.rs >+++ b/servo/components/style/sharing/mod.rs >@@ -59,37 +59,37 @@ > //! the up-front checks but would have different matching results for the > //! selector in question. In this case, "descendants" includes pseudo-elements, > //! so there is a single selector map of revalidation selectors that includes > //! both selectors targeting elements and selectors targeting pseudo-element > //! originating elements. We ensure that the pseudo-element parts of all these > //! selectors are effectively stripped off, so that matching them all against > //! elements makes sense. > >-use Atom; > use applicable_declarations::ApplicableDeclarationBlock; > use atomic_refcell::{AtomicRefCell, AtomicRefMut}; > use bloom::StyleBloom; > use context::{SelectorFlagsMap, SharedStyleContext, StyleContext}; > use dom::{SendElement, TElement}; > use matching::MatchMethods; > use owning_ref::OwningHandle; > use properties::ComputedValues; > use rule_tree::StrongRuleNode; >-use selectors::NthIndexCache; > use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode}; >+use selectors::NthIndexCache; > use servo_arc::{Arc, NonZeroPtrMut}; > use smallbitvec::SmallBitVec; > use smallvec::SmallVec; > use std::marker::PhantomData; > use std::mem; > use std::ops::Deref; > use style_resolver::{PrimaryStyle, ResolvedElementStyles}; > use stylist::Stylist; > use uluru::{Entry, LRUCache}; >+use Atom; > > mod checks; > > /// The amount of nodes that the style sharing candidate cache should hold at > /// most. We'd somewhat like 32, but ArrayDeque only implements certain backing > /// store sizes. A cache size of 32 would mean a backing store of 33, but > /// that's not an implemented size: we can do 32 or 40. > /// >@@ -192,18 +192,17 @@ impl ValidationData { > E: TElement, > { > self.parent_style_identity > .get_or_insert_with(|| { > let parent = el.inheritance_parent().unwrap(); > let values = > OpaqueComputedValues::from(parent.borrow_data().unwrap().styles.primary()); > values >- }) >- .clone() >+ }).clone() > } > > /// Computes the revalidation results if needed, and returns it. > /// Inline so we know at compile time what bloom_known_valid is. > #[inline] > fn revalidation_match_results<E, F>( > &mut self, > element: E, >@@ -557,17 +556,17 @@ impl<E: TElement> StyleSharingCache<E> { > validation_data_holder: Option<&mut StyleSharingTarget<E>>, > dom_depth: usize, > ) { > let parent = match element.traversal_parent() { > Some(element) => element, > None => { > debug!("Failing to insert to the cache: no parent element"); > return; >- }, >+ } > }; > > if element.is_in_native_anonymous_subtree() { > debug!("Failing to insert into the cache: NAC"); > return; > } > > // We can't share style across shadow hosts right now, because they may >@@ -755,18 +754,18 @@ impl<E: TElement> StyleSharingCache<E> { > return None; > } > > if target.element.shadow_root().is_some() { > trace!("Miss: Shadow host"); > return None; > } > >- if target.matches_user_and_author_rules() != >- candidate.element.matches_user_and_author_rules() >+ if target.matches_user_and_author_rules() >+ != candidate.element.matches_user_and_author_rules() > { > trace!("Miss: User and Author Rules"); > return None; > } > > // It's possible that there are no styles for either id. > let may_match_different_id_rules = > checks::may_match_different_id_rules(shared, target.element, candidate.element); >diff --git a/servo/components/style/str.rs b/servo/components/style/str.rs >index 4de65a235239..1d8fe0822872 100644 >--- a/servo/components/style/str.rs >+++ b/servo/components/style/str.rs >@@ -122,21 +122,21 @@ pub fn read_exponent<I: Iterator<Item = char>>(mut iter: Peekable<I>) -> Option< > } > iter.next(); > > match iter.peek() { > None => None, > Some(&'-') => { > iter.next(); > read_numbers(iter).0.map(|exp| -exp.to_i32().unwrap_or(0)) >- }, >+ } > Some(&'+') => { > iter.next(); > read_numbers(iter).0.map(|exp| exp.to_i32().unwrap_or(0)) >- }, >+ } > Some(_) => read_numbers(iter).0.map(|exp| exp.to_i32().unwrap_or(0)), > } > } > > /// Join a set of strings with a given delimiter `join`. > pub fn str_join<I, T>(strs: I, join: &str) -> String > where > I: IntoIterator<Item = T>, >@@ -150,18 +150,18 @@ where > } > acc.push_str(s.as_ref()); > acc > }) > } > > /// Returns true if a given string has a given prefix with case-insensitive match. > pub fn starts_with_ignore_ascii_case(string: &str, prefix: &str) -> bool { >- string.len() >= prefix.len() && >- string.as_bytes()[0..prefix.len()].eq_ignore_ascii_case(prefix.as_bytes()) >+ string.len() >= prefix.len() >+ && string.as_bytes()[0..prefix.len()].eq_ignore_ascii_case(prefix.as_bytes()) > } > > /// Returns an ascii lowercase version of a string, only allocating if needed. > pub fn string_as_ascii_lowercase<'a>(input: &'a str) -> Cow<'a, str> { > if input.bytes().any(|c| matches!(c, b'A'...b'Z')) { > input.to_ascii_lowercase().into() > } else { > // Already ascii lowercase. >@@ -195,17 +195,17 @@ pub enum CssStringBorrow<'a> { > #[cfg(feature = "gecko")] > impl<'a> CssStringBorrow<'a> { > /// Writes the borrowed string to the provided writer. > pub fn append_to(&self, dest: &mut CssStringWriter) -> fmt::Result { > match *self { > CssStringBorrow::UTF16(s) => { > dest.append(s); > Ok(()) >- }, >+ } > CssStringBorrow::UTF8(s) => dest.write_str(s), > } > } > > /// Returns true of the borrowed string is empty. > pub fn is_empty(&self) -> bool { > match *self { > CssStringBorrow::UTF16(s) => s.is_empty(), >diff --git a/servo/components/style/style_adjuster.rs b/servo/components/style/style_adjuster.rs >index 704c875a932e..73c5b6c5ee1c 100644 >--- a/servo/components/style/style_adjuster.rs >+++ b/servo/components/style/style_adjuster.rs >@@ -2,22 +2,22 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A struct to encapsulate all the style fixups and flags propagations > //! a computed style needs in order for it to adhere to the CSS spec. > > use app_units::Au; > use dom::TElement; >-use properties::{self, ComputedValues, StyleBuilder}; > use properties::computed_value_flags::ComputedValueFlags; > use properties::longhands::display::computed_value::T as Display; > use properties::longhands::float::computed_value::T as Float; > use properties::longhands::overflow_x::computed_value::T as Overflow; > use properties::longhands::position::computed_value::T as Position; >+use properties::{self, ComputedValues, StyleBuilder}; > > /// A struct that implements all the adjustment methods. > /// > /// NOTE(emilio): If new adjustments are introduced that depend on reset > /// properties of the parent, you may need tweaking the > /// `ChildCascadeRequirement` code in `matching.rs`. > /// > /// NOTE(emilio): Also, if new adjustments are introduced that break the >@@ -59,49 +59,68 @@ fn is_effective_display_none_for_display_contents<E>(element: E) -> bool > where > E: TElement, > { > use Atom; > > // FIXME(emilio): This should be an actual static. > lazy_static! { > static ref SPECIAL_HTML_ELEMENTS: [Atom; 16] = [ >- atom!("br"), atom!("wbr"), atom!("meter"), atom!("progress"), >- atom!("canvas"), atom!("embed"), atom!("object"), atom!("audio"), >- atom!("iframe"), atom!("img"), atom!("video"), atom!("frame"), >- atom!("frameset"), atom!("input"), atom!("textarea"), >+ atom!("br"), >+ atom!("wbr"), >+ atom!("meter"), >+ atom!("progress"), >+ atom!("canvas"), >+ atom!("embed"), >+ atom!("object"), >+ atom!("audio"), >+ atom!("iframe"), >+ atom!("img"), >+ atom!("video"), >+ atom!("frame"), >+ atom!("frameset"), >+ atom!("input"), >+ atom!("textarea"), > atom!("select"), > ]; > } > > // https://drafts.csswg.org/css-display/#unbox-svg > // > // There's a note about "Unknown elements", but there's not a good way to > // know what that means, or to get that information from here, and no other > // UA implements this either. > lazy_static! { > static ref SPECIAL_SVG_ELEMENTS: [Atom; 6] = [ >- atom!("svg"), atom!("a"), atom!("g"), atom!("use"), >- atom!("tspan"), atom!("textPath"), >+ atom!("svg"), >+ atom!("a"), >+ atom!("g"), >+ atom!("use"), >+ atom!("tspan"), >+ atom!("textPath"), > ]; > } > > // https://drafts.csswg.org/css-display/#unbox-html > if element.is_html_element() { > let local_name = element.local_name(); >- return SPECIAL_HTML_ELEMENTS.iter().any(|name| &**name == local_name); >+ return SPECIAL_HTML_ELEMENTS >+ .iter() >+ .any(|name| &**name == local_name); > } > > // https://drafts.csswg.org/css-display/#unbox-svg > if element.is_svg_element() { > if is_topmost_svg_svg_element(element) { > return true; > } > let local_name = element.local_name(); >- return !SPECIAL_SVG_ELEMENTS.iter().any(|name| &**name == local_name); >+ return !SPECIAL_SVG_ELEMENTS >+ .iter() >+ .any(|name| &**name == local_name); > } > > // https://drafts.csswg.org/css-display/#unbox-mathml > // > // We always treat XUL as display: none. We don't use display: > // contents in XUL anyway, so should be fine to be consistent with > // MathML unless there's a use case for it. > if element.is_mathml_element() || element.is_xul_element() { >@@ -196,21 +215,21 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > .set_adjusted_display(blockified_display, is_item_or_root); > } > } > > /// Compute a few common flags for both text and element's style. > pub fn set_bits(&mut self) { > let display = self.style.get_box().clone_display(); > >- if !display.is_contents() && >- !self.style >- .get_text() >- .clone_text_decoration_line() >- .is_empty() >+ if !display.is_contents() && !self >+ .style >+ .get_text() >+ .clone_text_decoration_line() >+ .is_empty() > { > self.style > .flags > .insert(ComputedValueFlags::HAS_TEXT_DECORATION_LINES); > } > > if self.style.is_pseudo_element() { > self.style >@@ -254,18 +273,18 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > #[cfg(feature = "gecko")] > fn adjust_for_text_combine_upright(&mut self) { > use computed_values::text_combine_upright::T as TextCombineUpright; > use computed_values::writing_mode::T as WritingMode; > > let writing_mode = self.style.get_inherited_box().clone_writing_mode(); > let text_combine_upright = self.style.get_inherited_text().clone_text_combine_upright(); > >- if writing_mode != WritingMode::HorizontalTb && >- text_combine_upright == TextCombineUpright::All >+ if writing_mode != WritingMode::HorizontalTb >+ && text_combine_upright == TextCombineUpright::All > { > self.style > .flags > .insert(ComputedValueFlags::IS_TEXT_COMBINED); > self.style > .mutate_inherited_box() > .set_writing_mode(WritingMode::HorizontalTb); > } >@@ -275,20 +294,20 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// additionally it applies it if it is in any ruby box. > /// > /// This is necessary because its parent may not itself have the flag set > /// (e.g. ruby or ruby containers), thus we may not inherit the flag from > /// them. > #[cfg(feature = "gecko")] > fn adjust_for_text_in_ruby(&mut self) { > let parent_display = self.style.get_parent_box().clone_display(); >- if parent_display.is_ruby_type() || >- self.style >- .get_parent_flags() >- .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK) >+ if parent_display.is_ruby_type() || self >+ .style >+ .get_parent_flags() >+ .contains(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK) > { > self.style > .flags > .insert(ComputedValueFlags::SHOULD_SUPPRESS_LINEBREAK); > } > } > > /// <https://drafts.csswg.org/css-writing-modes-3/#block-flow:> >@@ -303,18 +322,18 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// the spec. See also: > /// > /// <https://lists.w3.org/Archives/Public/www-style/2017Mar/0045.html> > /// <https://github.com/servo/servo/issues/15754> > fn adjust_for_writing_mode(&mut self, layout_parent_style: &ComputedValues) { > let our_writing_mode = self.style.get_inherited_box().clone_writing_mode(); > let parent_writing_mode = layout_parent_style.get_inherited_box().clone_writing_mode(); > >- if our_writing_mode != parent_writing_mode && >- self.style.get_box().clone_display() == Display::Inline >+ if our_writing_mode != parent_writing_mode >+ && self.style.get_box().clone_display() == Display::Inline > { > // TODO(emilio): Figure out if we can just set the adjusted display > // on Gecko too and unify this code path. > if cfg!(feature = "servo") { > self.style > .mutate_box() > .set_adjusted_display(Display::InlineBlock, false); > } else { >@@ -341,18 +360,18 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// this to layout, which Gecko implements but Servo doesn't. > /// > /// See https://github.com/servo/servo/issues/15229 > #[cfg(feature = "servo")] > fn adjust_for_alignment(&mut self, layout_parent_style: &ComputedValues) { > use computed_values::align_items::T as AlignItems; > use computed_values::align_self::T as AlignSelf; > >- if self.style.get_position().clone_align_self() == AlignSelf::Auto && >- !self.style.out_of_flow_positioned() >+ if self.style.get_position().clone_align_self() == AlignSelf::Auto >+ && !self.style.out_of_flow_positioned() > { > let self_align = match layout_parent_style.get_position().clone_align_items() { > AlignItems::Stretch => AlignSelf::Stretch, > AlignItems::Baseline => AlignSelf::Baseline, > AlignItems::FlexStart => AlignSelf::FlexStart, > AlignItems::FlexEnd => AlignSelf::FlexEnd, > AlignItems::Center => AlignSelf::Center, > }; >@@ -365,20 +384,22 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// > /// This is moved to properties.rs for convenience. > fn adjust_for_border_width(&mut self) { > properties::adjust_border_width(self.style); > } > > /// The initial value of outline-width may be changed at computed value time. > fn adjust_for_outline(&mut self) { >- if self.style >+ if self >+ .style > .get_outline() > .clone_outline_style() >- .none_or_hidden() && self.style.get_outline().outline_has_nonzero_width() >+ .none_or_hidden() >+ && self.style.get_outline().outline_has_nonzero_width() > { > self.style.mutate_outline().set_outline_width(Au(0).into()); > } > } > > /// CSS3 overflow-x and overflow-y require some fixup as well in some > /// cases. > /// >@@ -459,17 +480,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// this type into its ::-moz-fieldset-content anonymous box. > /// > /// NOTE(emilio): We don't need to handle the display change for this case > /// in matching.rs because anonymous box restyling works separately to the > /// normal cascading process. > #[cfg(feature = "gecko")] > fn adjust_for_fieldset_content(&mut self, layout_parent_style: &ComputedValues) { > match self.style.pseudo { >- Some(ref p) if p.is_fieldset_content() => {}, >+ Some(ref p) if p.is_fieldset_content() => {} > _ => return, > } > > debug_assert_eq!(self.style.get_box().clone_display(), Display::Block); > // TODO We actually want style from parent rather than layout > // parent, so that this fixup doesn't happen incorrectly when > // when <fieldset> has "display: contents". > let parent_display = layout_parent_style.get_box().clone_display(); >@@ -492,17 +513,17 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > #[cfg(feature = "gecko")] > fn adjust_for_table_text_align(&mut self) { > use properties::longhands::text_align::computed_value::T as TextAlign; > if self.style.get_box().clone_display() != Display::Table { > return; > } > > match self.style.get_inherited_text().clone_text_align() { >- TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {}, >+ TextAlign::MozLeft | TextAlign::MozCenter | TextAlign::MozRight => {} > _ => return, > } > > self.style > .mutate_inherited_text() > .set_text_align(TextAlign::Start) > } > >@@ -512,17 +533,19 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > /// style, since otherwise we're going to have the same subtle bugs WebKit > /// and Blink have with this very same thing. > #[cfg(feature = "servo")] > fn adjust_for_text_decorations_in_effect(&mut self) { > use values::computed::text::TextDecorationsInEffect; > > let decorations_in_effect = TextDecorationsInEffect::from_style(&self.style); > if self.style.get_inherited_text().text_decorations_in_effect != decorations_in_effect { >- self.style.mutate_inherited_text().text_decorations_in_effect = decorations_in_effect; >+ self.style >+ .mutate_inherited_text() >+ .text_decorations_in_effect = decorations_in_effect; > } > } > > #[cfg(feature = "gecko")] > fn should_suppress_linebreak(&self, layout_parent_style: &ComputedValues) -> bool { > // Line break suppression should only be propagated to in-flow children. > if self.style.floated() || self.style.out_of_flow_positioned() { > return false; >@@ -672,21 +695,18 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { > } > > /// Adjusts the style to account for various fixups that don't fit naturally > /// into the cascade. > /// > /// When comparing to Gecko, this is similar to the work done by > /// `ComputedStyle::ApplyStyleFixups`, plus some parts of > /// `nsStyleSet::GetContext`. >- pub fn adjust<E>( >- &mut self, >- layout_parent_style: &ComputedValues, >- element: Option<E>, >- ) where >+ pub fn adjust<E>(&mut self, layout_parent_style: &ComputedValues, element: Option<E>) >+ where > E: TElement, > { > if cfg!(debug_assertions) { > if element > .and_then(|e| e.implemented_pseudo_element()) > .is_some() > { > // It'd be nice to assert `self.style.pseudo == Some(&pseudo)`, >diff --git a/servo/components/style/style_resolver.rs b/servo/components/style/style_resolver.rs >index b31beff74603..2a15844cf953 100644 >--- a/servo/components/style/style_resolver.rs >+++ b/servo/components/style/style_resolver.rs >@@ -5,21 +5,23 @@ > //! Style resolution for a given element or pseudo-element. > > use applicable_declarations::ApplicableDeclarationList; > use context::{CascadeInputs, ElementCascadeInputs, StyleContext}; > use data::{EagerPseudoStyles, ElementStyles}; > use dom::TElement; > use log::Level::Trace; > use matching::MatchMethods; >-use properties::{AnimationRules, ComputedValues}; > use properties::longhands::display::computed_value::T as Display; >+use properties::{AnimationRules, ComputedValues}; > use rule_tree::StrongRuleNode; > use selector_parser::{PseudoElement, SelectorImpl}; >-use selectors::matching::{ElementSelectorFlags, MatchingContext, MatchingMode, VisitedHandlingMode}; >+use selectors::matching::{ >+ ElementSelectorFlags, MatchingContext, MatchingMode, VisitedHandlingMode, >+}; > use servo_arc::Arc; > use stylist::RuleInclusion; > > /// Whether pseudo-elements should be resolved or not. > #[derive(Clone, Copy, Debug, Eq, PartialEq)] > pub enum PseudoElementResolution { > /// Only resolve pseudo-styles if possibly applicable. > IfApplicable, >@@ -110,24 +112,24 @@ fn eager_pseudo_is_definitely_not_generated( > style: &ComputedValues, > ) -> bool { > use properties::computed_value_flags::ComputedValueFlags; > > if !pseudo.is_before_or_after() { > return false; > } > >- if !style.flags.intersects(ComputedValueFlags::INHERITS_DISPLAY) && >- style.get_box().clone_display() == Display::None >+ if !style.flags.intersects(ComputedValueFlags::INHERITS_DISPLAY) >+ && style.get_box().clone_display() == Display::None > { > return true; > } > >- if !style.flags.intersects(ComputedValueFlags::INHERITS_CONTENT) && >- style.ineffective_content_property() >+ if !style.flags.intersects(ComputedValueFlags::INHERITS_CONTENT) >+ && style.ineffective_content_property() > { > return true; > } > > false > } > > impl<'a, 'ctx, 'le, E> StyleResolverForElement<'a, 'ctx, 'le, E> >@@ -157,18 +159,18 @@ where > &mut self, > parent_style: Option<&ComputedValues>, > layout_parent_style: Option<&ComputedValues>, > ) -> PrimaryStyle { > let primary_results = self.match_primary(VisitedHandlingMode::AllLinksUnvisited); > > let inside_link = parent_style.map_or(false, |s| s.visited_style().is_some()); > >- let visited_rules = if self.context.shared.visited_styles_enabled && >- (inside_link || self.element.is_link()) >+ let visited_rules = if self.context.shared.visited_styles_enabled >+ && (inside_link || self.element.is_link()) > { > let visited_matching_results = > self.match_primary(VisitedHandlingMode::RelevantLinkVisited); > Some(visited_matching_results.rule_node) > } else { > None > }; > >@@ -185,20 +187,19 @@ where > fn cascade_primary_style( > &mut self, > inputs: CascadeInputs, > parent_style: Option<&ComputedValues>, > layout_parent_style: Option<&ComputedValues>, > ) -> PrimaryStyle { > // Before doing the cascade, check the sharing cache and see if we can > // reuse the style via rule node identity. >- let may_reuse = >- !self.element.is_in_native_anonymous_subtree() && >- parent_style.is_some() && >- inputs.rules.is_some(); >+ let may_reuse = !self.element.is_in_native_anonymous_subtree() >+ && parent_style.is_some() >+ && inputs.rules.is_some(); > > if may_reuse { > let cached = self.context.thread_local.sharing_cache.lookup_by_rules( > self.context.shared, > parent_style.unwrap(), > inputs.rules.as_ref().unwrap(), > inputs.visited_rules.as_ref(), > self.element, >@@ -242,18 +243,18 @@ where > SelectorImpl::each_eagerly_cascaded_pseudo_element(|pseudo| { > let pseudo_style = self.resolve_pseudo_style( > &pseudo, > &primary_style, > layout_parent_style_for_pseudo, > ); > > if let Some(style) = pseudo_style { >- if !matches!(self.pseudo_resolution, PseudoElementResolution::Force) && >- eager_pseudo_is_definitely_not_generated(&pseudo, &style.0) >+ if !matches!(self.pseudo_resolution, PseudoElementResolution::Force) >+ && eager_pseudo_is_definitely_not_generated(&pseudo, &style.0) > { > return; > } > pseudo_styles.set(&pseudo, style.0); > } > }) > } > >@@ -350,18 +351,18 @@ where > > let style = self.cascade_style_and_visited( > inputs, > Some(primary_style.style()), > layout_parent_style_for_pseudo, > Some(&pseudo), > ); > >- if !matches!(self.pseudo_resolution, PseudoElementResolution::Force) && >- eager_pseudo_is_definitely_not_generated(&pseudo, &style.0) >+ if !matches!(self.pseudo_resolution, PseudoElementResolution::Force) >+ && eager_pseudo_is_definitely_not_generated(&pseudo, &style.0) > { > continue; > } > > pseudo_styles.set(&pseudo, style.0); > } > } > } >@@ -480,17 +481,18 @@ where > self.element.implemented_pseudo_element().is_none(), > "Element pseudos can't have any other pseudo." > ); > > let mut applicable_declarations = ApplicableDeclarationList::new(); > > let stylist = &self.context.shared.stylist; > >- if !self.element >+ if !self >+ .element > .may_generate_pseudo(pseudo_element, originating_element_style) > { > return None; > } > > let bloom_filter = self.context.thread_local.bloom_filter.filter(); > let nth_index_cache = &mut self.context.thread_local.nth_index_cache; > >diff --git a/servo/components/style/stylesheet_set.rs b/servo/components/style/stylesheet_set.rs >index a3b6e5cdc17e..19790aba9574 100644 >--- a/servo/components/style/stylesheet_set.rs >+++ b/servo/components/style/stylesheet_set.rs >@@ -319,17 +319,18 @@ where > // But we need to be marked as dirty, otherwise we'll never add the new > // sheet! > self.dirty = true; > } > > fn insert_before(&mut self, sheet: S, before_sheet: &S) { > debug_assert!(!self.contains(&sheet)); > >- let index = self.entries >+ let index = self >+ .entries > .iter() > .position(|entry| entry.sheet == *before_sheet) > .expect("`before_sheet` stylesheet not found"); > > // Inserting stylesheets somewhere but at the end changes the validity > // of the cascade data, but not the invalidation data. > self.set_data_validity_at_least(DataValidity::CascadeInvalid); > self.entries.insert(index, StylesheetSetEntry::new(sheet)); >diff --git a/servo/components/style/stylesheets/document_rule.rs b/servo/components/style/stylesheets/document_rule.rs >index 56750ae7b66f..50e5433b86c6 100644 >--- a/servo/components/style/stylesheets/document_rule.rs >+++ b/servo/components/style/stylesheets/document_rule.rs >@@ -31,18 +31,18 @@ pub struct DocumentRule { > pub source_location: SourceLocation, > } > > impl DocumentRule { > /// Measure heap usage. > #[cfg(feature = "gecko")] > pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { > // Measurement of other fields may be added later. >- self.rules.unconditional_shallow_size_of(ops) + >- self.rules.read_with(guard).size_of(guard, ops) >+ self.rules.unconditional_shallow_size_of(ops) >+ + self.rules.read_with(guard).size_of(guard, ops) > } > } > > impl ToCssWithGuard for DocumentRule { > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > dest.write_str("@-moz-document ")?; > self.condition.to_css(&mut CssWriter::new(dest))?; > dest.write_str(" {")?; >@@ -104,44 +104,43 @@ pub enum DocumentMatchingFunction { > Domain(String), > /// Regular expression matching function. It evaluates to true > /// whenever the regular expression matches the entirety of the URL > /// of the document being styled. > #[css(function)] > Regexp(String), > /// Matching function for a media document. > #[css(function)] >- MediaDocument(MediaDocumentKind) >+ MediaDocument(MediaDocumentKind), > } > > macro_rules! parse_quoted_or_unquoted_string { > ($input:ident, $url_matching_function:expr) => { > $input.parse_nested_block(|input| { > let start = input.position(); > input > .parse_entirely(|input| { > let string = input.expect_string()?; > Ok($url_matching_function(string.as_ref().to_owned())) >- }) >- .or_else(|_: ParseError| { >+ }).or_else(|_: ParseError| { > while let Ok(_) = input.next() {} > Ok($url_matching_function(input.slice_from(start).to_string())) > }) > }) > }; > } > > impl DocumentMatchingFunction { > /// Parse a URL matching function for a`@document` rule's condition. > pub fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > if let Ok(url) = input.try(|input| CssUrl::parse(context, input)) { >- return Ok(DocumentMatchingFunction::Url(url)) >+ return Ok(DocumentMatchingFunction::Url(url)); > } > > let location = input.current_source_location(); > let function = input.expect_function()?.clone(); > match_ignore_ascii_case! { &function, > "url-prefix" => { > parse_quoted_or_unquoted_string!(input, DocumentMatchingFunction::UrlPrefix) > } >@@ -176,32 +175,32 @@ impl DocumentMatchingFunction { > use gecko_bindings::structs::DocumentMatchingFunction as GeckoDocumentMatchingFunction; > use nsstring::nsCStr; > > let func = match *self { > DocumentMatchingFunction::Url(_) => GeckoDocumentMatchingFunction::URL, > DocumentMatchingFunction::UrlPrefix(_) => GeckoDocumentMatchingFunction::URLPrefix, > DocumentMatchingFunction::Domain(_) => GeckoDocumentMatchingFunction::Domain, > DocumentMatchingFunction::Regexp(_) => GeckoDocumentMatchingFunction::RegExp, >- DocumentMatchingFunction::MediaDocument(_) => GeckoDocumentMatchingFunction::MediaDocument, >+ DocumentMatchingFunction::MediaDocument(_) => { >+ GeckoDocumentMatchingFunction::MediaDocument >+ } > }; > > let pattern = nsCStr::from(match *self { > DocumentMatchingFunction::Url(ref url) => url.as_str(), >- DocumentMatchingFunction::UrlPrefix(ref pat) | >- DocumentMatchingFunction::Domain(ref pat) | >- DocumentMatchingFunction::Regexp(ref pat) => pat, >- DocumentMatchingFunction::MediaDocument(kind) => { >- match kind { >- MediaDocumentKind::All => "all", >- MediaDocumentKind::Image => "image", >- MediaDocumentKind::Plugin => "plugin", >- MediaDocumentKind::Video => "video", >- } >- } >+ DocumentMatchingFunction::UrlPrefix(ref pat) >+ | DocumentMatchingFunction::Domain(ref pat) >+ | DocumentMatchingFunction::Regexp(ref pat) => pat, >+ DocumentMatchingFunction::MediaDocument(kind) => match kind { >+ MediaDocumentKind::All => "all", >+ MediaDocumentKind::Image => "image", >+ MediaDocumentKind::Plugin => "plugin", >+ MediaDocumentKind::Video => "video", >+ }, > }); > unsafe { Gecko_DocumentRule_UseForPresentation(device.pres_context(), &*pattern, func) } > } > > #[cfg(not(feature = "gecko"))] > /// Evaluate a URL matching function. > pub fn evaluate(&self, _: &Device) -> bool { > false >diff --git a/servo/components/style/stylesheets/font_feature_values_rule.rs b/servo/components/style/stylesheets/font_feature_values_rule.rs >index c70a46c1c9d2..f1edaa2ea6b2 100644 >--- a/servo/components/style/stylesheets/font_feature_values_rule.rs >+++ b/servo/components/style/stylesheets/font_feature_values_rule.rs >@@ -1,33 +1,33 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! The [`@font-feature-values`][font-feature-values] at-rule. > //! > //! [font-feature-values]: https://drafts.csswg.org/css-fonts-3/#at-font-feature-values-rule > >-use Atom; > use cssparser::{AtRuleParser, AtRuleType, BasicParseErrorKind, CowRcStr}; > use cssparser::{DeclarationListParser, DeclarationParser, Parser}; > use cssparser::{QualifiedRuleParser, RuleListParser, SourceLocation, Token}; > use error_reporting::ContextualParseError; > #[cfg(feature = "gecko")] > use gecko_bindings::bindings::Gecko_AppendFeatureValueHashEntry; > #[cfg(feature = "gecko")] > use gecko_bindings::structs::{self, gfxFontFeatureValueSet, nsTArray}; > use parser::{Parse, ParserContext}; > use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use stylesheets::CssRuleType; > use values::computed::font::FamilyName; > use values::serialize_atom_identifier; >+use Atom; > > /// A @font-feature-values block declaration. > /// It is `<ident>: <integer>+`. > /// This struct can take 3 value types. > /// - `SingleValue` is to keep just one unsigned integer value. > /// - `PairValues` is to keep one or two unsigned integer values. > /// - `VectorValues` is to keep a list of unsigned integer values. > #[derive(Clone, Debug, PartialEq)] >@@ -65,20 +65,21 @@ impl Parse for SingleValue { > fn parse<'i, 't>( > _context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<SingleValue, ParseError<'i>> { > let location = input.current_source_location(); > match *input.next()? { > Token::Number { > int_value: Some(v), .. >- } if v >= 0 => >+ } >+ if v >= 0 => > { > Ok(SingleValue(v as u32)) >- }, >+ } > ref t => Err(location.new_unexpected_token_error(t.clone())), > } > } > } > > #[cfg(feature = "gecko")] > impl ToGeckoFontFeatureValues for SingleValue { > fn to_gecko_font_feature_values(&self, array: &mut nsTArray<u32>) { >@@ -97,30 +98,32 @@ impl Parse for PairValues { > fn parse<'i, 't>( > _context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<PairValues, ParseError<'i>> { > let location = input.current_source_location(); > let first = match *input.next()? { > Token::Number { > int_value: Some(a), .. >- } if a >= 0 => >+ } >+ if a >= 0 => > { > a as u32 >- }, >+ } > ref t => return Err(location.new_unexpected_token_error(t.clone())), > }; > let location = input.current_source_location(); > match input.next() { > Ok(&Token::Number { > int_value: Some(b), .. >- }) if b >= 0 => >+ }) >+ if b >= 0 => > { > Ok(PairValues(first, Some(b as u32))) >- }, >+ } > // It can't be anything other than number. > Ok(t) => Err(location.new_unexpected_token_error(t.clone())), > // It can be just one value. > Err(_) => Ok(PairValues(first, None)), > } > } > } > >@@ -149,17 +152,18 @@ impl Parse for VectorValues { > input: &mut Parser<'i, 't>, > ) -> Result<VectorValues, ParseError<'i>> { > let mut vec = vec![]; > loop { > let location = input.current_source_location(); > match input.next() { > Ok(&Token::Number { > int_value: Some(a), .. >- }) if a >= 0 => >+ }) >+ if a >= 0 => > { > vec.push(a as u32); > } > // It can't be anything other than number. > Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), > Err(_) => break, > } > } >diff --git a/servo/components/style/stylesheets/import_rule.rs b/servo/components/style/stylesheets/import_rule.rs >index 576cb31eff30..68b26734505c 100644 >--- a/servo/components/style/stylesheets/import_rule.rs >+++ b/servo/components/style/stylesheets/import_rule.rs >@@ -72,17 +72,17 @@ impl DeepCloneWithLock for ImportSheet { > use gecko::data::GeckoStyleSheet; > use gecko_bindings::bindings; > match *self { > ImportSheet::Sheet(ref s) => { > let clone = unsafe { > bindings::Gecko_StyleSheet_Clone(s.raw() as *const _, params.reference_sheet) > }; > ImportSheet::Sheet(unsafe { GeckoStyleSheet::from_addrefed(clone) }) >- }, >+ } > ImportSheet::Pending(ref p) => ImportSheet::Pending(p.clone()), > } > } > } > > #[cfg(feature = "gecko")] > impl StylesheetInDocument for ImportSheet { > fn origin(&self, _guard: &SharedRwLockReadGuard) -> Origin { >@@ -199,15 +199,15 @@ impl ToCssWithGuard for ImportRule { > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > dest.write_str("@import ")?; > self.url.to_css(&mut CssWriter::new(dest))?; > > match self.stylesheet.media(guard) { > Some(media) if !media.is_empty() => { > dest.write_str(" ")?; > media.to_css(&mut CssWriter::new(dest))?; >- }, >- _ => {}, >+ } >+ _ => {} > }; > > dest.write_str(";") > } > } >diff --git a/servo/components/style/stylesheets/keyframes_rule.rs b/servo/components/style/stylesheets/keyframes_rule.rs >index 91bc14be5b59..633da6163df9 100644 >--- a/servo/components/style/stylesheets/keyframes_rule.rs >+++ b/servo/components/style/stylesheets/keyframes_rule.rs >@@ -1,31 +1,31 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Keyframes: https://drafts.csswg.org/css-animations/#keyframes > >-use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser}; > use cssparser::{parse_one_rule, DeclarationListParser, DeclarationParser, SourceLocation, Token}; >+use cssparser::{AtRuleParser, CowRcStr, Parser, ParserInput, QualifiedRuleParser, RuleListParser}; > use error_reporting::ContextualParseError; > use parser::ParserContext; >+use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; >+use properties::LonghandIdSet; > use properties::{Importance, PropertyDeclaration}; > use properties::{LonghandId, PropertyDeclarationBlock, PropertyId}; > use properties::{PropertyDeclarationId, SourcePropertyDeclaration}; >-use properties::LonghandIdSet; >-use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; > use servo_arc::Arc; > use shared_lock::{DeepCloneParams, DeepCloneWithLock, SharedRwLock, SharedRwLockReadGuard}; > use shared_lock::{Locked, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; > use style_traits::{CssWriter, ParseError, ParsingMode, StyleParseErrorKind, ToCss}; >-use stylesheets::{CssRuleType, StylesheetContents}; > use stylesheets::rule_parser::VendorPrefix; >+use stylesheets::{CssRuleType, StylesheetContents}; > use values::{serialize_percentage, KeyframesName}; > > /// A [`@keyframes`][keyframes] rule. > /// > /// [keyframes]: https://drafts.csswg.org/css-animations/#keyframes > #[derive(Debug)] > pub struct KeyframesRule { > /// The name of the current animation. >@@ -77,26 +77,24 @@ impl DeepCloneWithLock for KeyframesRule { > fn deep_clone_with_lock( > &self, > lock: &SharedRwLock, > guard: &SharedRwLockReadGuard, > params: &DeepCloneParams, > ) -> Self { > KeyframesRule { > name: self.name.clone(), >- keyframes: self.keyframes >+ keyframes: self >+ .keyframes > .iter() > .map(|x| { >- Arc::new(lock.wrap(x.read_with(guard).deep_clone_with_lock( >- lock, >- guard, >- params, >- ))) >- }) >- .collect(), >+ Arc::new( >+ lock.wrap(x.read_with(guard).deep_clone_with_lock(lock, guard, params)), >+ ) >+ }).collect(), > vendor_prefix: self.vendor_prefix.clone(), > source_location: self.source_location.clone(), > } > } > } > > /// A number from 0 to 1, indicating the percentage of the animation when this > /// keyframe should run. >@@ -130,27 +128,28 @@ impl KeyframePercentage { > KeyframePercentage(value) > } > > fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<KeyframePercentage, ParseError<'i>> { > let token = input.next()?.clone(); > match token { > Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("from") => { > Ok(KeyframePercentage::new(0.)) >- }, >+ } > Token::Ident(ref identifier) if identifier.as_ref().eq_ignore_ascii_case("to") => { > Ok(KeyframePercentage::new(1.)) >- }, >+ } > Token::Percentage { > unit_value: percentage, > .. >- } if percentage >= 0. && percentage <= 1. => >+ } >+ if percentage >= 0. && percentage <= 1. => > { > Ok(KeyframePercentage::new(percentage)) >- }, >+ } > _ => Err(input.new_unexpected_token_error(token)), > } > } > } > > /// A keyframes selector is a list of percentages or from/to symbols, which are > /// converted at parse time to percentages. > #[css(comma)] >@@ -255,18 +254,20 @@ impl DeepCloneWithLock for Keyframe { > /// declarations to apply. > /// > /// TODO: Find a better name for this? > #[derive(Clone, Debug, MallocSizeOf)] > pub enum KeyframesStepValue { > /// A step formed by a declaration block specified by the CSS. > Declarations { > /// The declaration block per se. >- #[cfg_attr(feature = "gecko", >- ignore_malloc_size_of = "XXX: Primary ref, measure if DMD says it's worthwhile")] >+ #[cfg_attr( >+ feature = "gecko", >+ ignore_malloc_size_of = "XXX: Primary ref, measure if DMD says it's worthwhile" >+ )] > #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] > block: Arc<Locked<PropertyDeclarationBlock>>, > }, > /// A synthetic step computed from the current computed values at the time > /// of the animation. > ComputedValues, > } > >@@ -320,31 +321,30 @@ impl KeyframesStep { > return None; > } > match self.value { > KeyframesStepValue::Declarations { ref block } => { > let guard = block.read_with(guard); > let (declaration, _) = guard > .get(PropertyDeclarationId::Longhand( > LonghandId::AnimationTimingFunction, >- )) >- .unwrap(); >+ )).unwrap(); > match *declaration { > PropertyDeclaration::AnimationTimingFunction(ref value) => { > // Use the first value. > Some(value.0[0]) >- }, >+ } > PropertyDeclaration::CSSWideKeyword(..) => None, > PropertyDeclaration::WithVariables(..) => None, > _ => panic!(), > } >- }, >+ } > KeyframesStepValue::ComputedValues => { > panic!("Shouldn't happen to set animation-timing-function in missing keyframes") >- }, >+ } > } > } > } > > /// This structure represents a list of animation steps computed from the list > /// of keyframes, in order. > /// > /// It only takes into account animable properties. >@@ -494,17 +494,17 @@ pub fn parse_keyframe_list( > RuleListParser::new_for_nested_rule( > input, > KeyframeListParser { > context: context, > shared_lock: shared_lock, > declarations: &mut declarations, > }, > ).filter_map(Result::ok) >- .collect() >+ .collect() > } > > impl<'a, 'i> AtRuleParser<'i> for KeyframeListParser<'a> { > type PreludeNoBlock = (); > type PreludeBlock = (); > type AtRule = Arc<Locked<Keyframe>>; > type Error = StyleParseErrorKind<'i>; > } >@@ -519,17 +519,17 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { > input: &mut Parser<'i, 't>, > ) -> Result<Self::Prelude, ParseError<'i>> { > let start_position = input.position(); > KeyframeSelector::parse(input).map_err(|e| { > let location = e.location; > let error = ContextualParseError::InvalidKeyframeRule( > input.slice_from(start_position), > e.clone(), >- ); >+ ); > self.context.log_css_error(location, error); > e > }) > } > > fn parse_block<'t>( > &mut self, > selector: Self::Prelude, >@@ -546,28 +546,25 @@ impl<'a, 'i> QualifiedRuleParser<'i> for KeyframeListParser<'a> { > context: &context, > declarations: self.declarations, > }; > let mut iter = DeclarationListParser::new(input, parser); > let mut block = PropertyDeclarationBlock::new(); > while let Some(declaration) = iter.next() { > match declaration { > Ok(()) => { >- block.extend( >- iter.parser.declarations.drain(), >- Importance::Normal, >- ); >- }, >+ block.extend(iter.parser.declarations.drain(), Importance::Normal); >+ } > Err((error, slice)) => { > iter.parser.declarations.clear(); > let location = error.location; > let error = > ContextualParseError::UnsupportedKeyframePropertyDeclaration(slice, error); > context.log_css_error(location, error); >- }, >+ } > } > // `parse_important` is not called here, `!important` is not allowed in keyframe blocks. > } > Ok(Arc::new(self.shared_lock.wrap(Keyframe { > selector, > block: Arc::new(self.shared_lock.wrap(block)), > source_location, > }))) >@@ -593,19 +590,19 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for KeyframeDeclarationParser<'a, 'b> { > > fn parse_value<'t>( > &mut self, > name: CowRcStr<'i>, > input: &mut Parser<'i, 't>, > ) -> Result<(), ParseError<'i>> { > let id = match PropertyId::parse(&name, self.context) { > Ok(id) => id, >- Err(()) => return Err(input.new_custom_error( >- StyleParseErrorKind::UnknownProperty(name) >- )), >+ Err(()) => { >+ return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name))) >+ } > }; > > // TODO(emilio): Shouldn't this use parse_entirely? > PropertyDeclaration::parse_into(self.declarations, id, self.context, input)?; > > // In case there is still unparsed text in the declaration, we should > // roll back. > input.expect_exhausted()?; >diff --git a/servo/components/style/stylesheets/media_rule.rs b/servo/components/style/stylesheets/media_rule.rs >index 4ae54c18f2b0..791a5c276caf 100644 >--- a/servo/components/style/stylesheets/media_rule.rs >+++ b/servo/components/style/stylesheets/media_rule.rs >@@ -31,18 +31,18 @@ pub struct MediaRule { > pub source_location: SourceLocation, > } > > impl MediaRule { > /// Measure heap usage. > #[cfg(feature = "gecko")] > pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { > // Measurement of other fields may be added later. >- self.rules.unconditional_shallow_size_of(ops) + >- self.rules.read_with(guard).size_of(guard, ops) >+ self.rules.unconditional_shallow_size_of(ops) >+ + self.rules.read_with(guard).size_of(guard, ops) > } > } > > impl ToCssWithGuard for MediaRule { > // Serialization of MediaRule is not specced. > // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSMediaRule > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > dest.write_str("@media ")?; >diff --git a/servo/components/style/stylesheets/mod.rs b/servo/components/style/stylesheets/mod.rs >index e3641f3e5151..657af72c4706 100644 >--- a/servo/components/style/stylesheets/mod.rs >+++ b/servo/components/style/stylesheets/mod.rs >@@ -40,35 +40,35 @@ pub use self::font_face_rule::FontFaceRule; > pub use self::font_feature_values_rule::FontFeatureValuesRule; > pub use self::import_rule::ImportRule; > pub use self::keyframes_rule::KeyframesRule; > pub use self::loader::StylesheetLoader; > pub use self::media_rule::MediaRule; > pub use self::namespace_rule::NamespaceRule; > pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter}; > pub use self::page_rule::PageRule; >-pub use self::rule_parser::{State, TopLevelRuleParser, InsertRuleContext}; > pub use self::rule_list::{CssRules, CssRulesHelpers}; >+pub use self::rule_parser::{InsertRuleContext, State, TopLevelRuleParser}; > pub use self::rules_iterator::{AllRules, EffectiveRules}; > pub use self::rules_iterator::{NestedRuleIterationCondition, RulesIterator}; >+pub use self::style_rule::StyleRule; > pub use self::stylesheet::{DocumentStyleSheet, Namespaces, Stylesheet}; > pub use self::stylesheet::{StylesheetContents, StylesheetInDocument, UserAgentStylesheets}; >-pub use self::style_rule::StyleRule; > pub use self::supports_rule::SupportsRule; > pub use self::viewport_rule::ViewportRule; > > /// Extra data that the backend may need to resolve url values. > #[cfg(not(feature = "gecko"))] > pub type UrlExtraData = ::servo_url::ServoUrl; > > /// Extra data that the backend may need to resolve url values. > #[cfg(feature = "gecko")] > #[derive(Clone, PartialEq)] > pub struct UrlExtraData( >- pub ::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData> >+ pub ::gecko_bindings::sugar::refptr::RefPtr<::gecko_bindings::structs::URLExtraData>, > ); > > #[cfg(feature = "gecko")] > impl UrlExtraData { > /// True if this URL scheme is chrome. > #[inline] > pub fn is_chrome(&self) -> bool { > self.0.mIsChrome >@@ -83,35 +83,38 @@ impl UrlExtraData { > pub unsafe fn from_ptr_ref(ptr: &*mut ::gecko_bindings::structs::URLExtraData) -> &Self { > ::std::mem::transmute(ptr) > } > } > > #[cfg(feature = "gecko")] > impl fmt::Debug for UrlExtraData { > fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { >- use gecko_bindings::{structs, bindings}; >+ use gecko_bindings::{bindings, structs}; > > struct DebugURI(*mut structs::nsIURI); > impl fmt::Debug for DebugURI { > fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { > use nsstring::nsCString; > let mut spec = nsCString::new(); > unsafe { > bindings::Gecko_nsIURI_Debug(self.0, &mut spec); > } > spec.fmt(formatter) > } > } > >- formatter.debug_struct("URLExtraData") >+ formatter >+ .debug_struct("URLExtraData") > .field("is_chrome", &self.is_chrome()) > .field("base", &DebugURI(self.0.mBaseURI.raw::<structs::nsIURI>())) >- .field("referrer", &DebugURI(self.0.mReferrer.raw::<structs::nsIURI>())) >- .finish() >+ .field( >+ "referrer", >+ &DebugURI(self.0.mReferrer.raw::<structs::nsIURI>()), >+ ).finish() > } > } > > // XXX We probably need to figure out whether we should mark Eq here. > // It is currently marked so because properties::UnparsedValue wants Eq. > #[cfg(feature = "gecko")] > impl Eq for UrlExtraData {} > >@@ -147,39 +150,39 @@ impl CssRule { > CssRule::Namespace(_) => 0, > > // We don't need to measure ImportRule::stylesheet because we measure > // it on the C++ side in the child list of the ServoStyleSheet. > CssRule::Import(_) => 0, > > CssRule::Style(ref lock) => { > lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops) >- }, >+ } > > CssRule::Media(ref lock) => { > lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops) >- }, >+ } > > CssRule::FontFace(_) => 0, > CssRule::FontFeatureValues(_) => 0, > CssRule::CounterStyle(_) => 0, > CssRule::Viewport(_) => 0, > CssRule::Keyframes(_) => 0, > > CssRule::Supports(ref lock) => { > lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops) >- }, >+ } > > CssRule::Page(ref lock) => { > lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops) >- }, >+ } > > CssRule::Document(ref lock) => { > lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops) >- }, >+ } > } > } > } > > #[allow(missing_docs)] > #[derive(Clone, Copy, Debug, Eq, PartialEq)] > pub enum CssRuleType { > // https://drafts.csswg.org/cssom/#the-cssrule-interface >@@ -279,104 +282,91 @@ impl CssRule { > loader, > state, > dom_error: None, > namespaces: &mut *guard, > insert_rule_context: Some(insert_rule_context), > }; > > parse_one_rule(&mut input, &mut rule_parser) >- .map_err(|_| { >- rule_parser.dom_error.unwrap_or(RulesMutateError::Syntax) >- }) >+ .map_err(|_| rule_parser.dom_error.unwrap_or(RulesMutateError::Syntax)) > } > } > > impl DeepCloneWithLock for CssRule { > /// Deep clones this CssRule. > fn deep_clone_with_lock( > &self, > lock: &SharedRwLock, > guard: &SharedRwLockReadGuard, > params: &DeepCloneParams, > ) -> CssRule { > match *self { > CssRule::Namespace(ref arc) => { > let rule = arc.read_with(guard); > CssRule::Namespace(Arc::new(lock.wrap(rule.clone()))) >- }, >+ } > CssRule::Import(ref arc) => { >- let rule = arc.read_with(guard) >+ let rule = arc >+ .read_with(guard) > .deep_clone_with_lock(lock, guard, params); > CssRule::Import(Arc::new(lock.wrap(rule))) >- }, >+ } > CssRule::Style(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Style(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Style(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > CssRule::Media(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Media(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Media(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > CssRule::FontFace(ref arc) => { > let rule = arc.read_with(guard); > CssRule::FontFace(Arc::new(lock.wrap(rule.clone()))) >- }, >+ } > CssRule::FontFeatureValues(ref arc) => { > let rule = arc.read_with(guard); > CssRule::FontFeatureValues(Arc::new(lock.wrap(rule.clone()))) >- }, >+ } > CssRule::CounterStyle(ref arc) => { > let rule = arc.read_with(guard); > CssRule::CounterStyle(Arc::new(lock.wrap(rule.clone()))) >- }, >+ } > CssRule::Viewport(ref arc) => { > let rule = arc.read_with(guard); > CssRule::Viewport(Arc::new(lock.wrap(rule.clone()))) >- }, >+ } > CssRule::Keyframes(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Keyframes(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Keyframes(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > CssRule::Supports(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Supports(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Supports(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > CssRule::Page(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Page(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Page(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > CssRule::Document(ref arc) => { > let rule = arc.read_with(guard); >- CssRule::Document(Arc::new(lock.wrap(rule.deep_clone_with_lock( >- lock, >- guard, >- params, >- )))) >- }, >+ CssRule::Document(Arc::new( >+ lock.wrap(rule.deep_clone_with_lock(lock, guard, params)), >+ )) >+ } > } > } > } > > impl ToCssWithGuard for CssRule { > // https://drafts.csswg.org/cssom/#serialize-a-css-rule > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > match *self { >diff --git a/servo/components/style/stylesheets/namespace_rule.rs b/servo/components/style/stylesheets/namespace_rule.rs >index f28f2ba0881a..1f927f08f172 100644 >--- a/servo/components/style/stylesheets/namespace_rule.rs >+++ b/servo/components/style/stylesheets/namespace_rule.rs >@@ -1,19 +1,19 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! The `@namespace` at-rule. > >-use {Namespace, Prefix}; > use cssparser::SourceLocation; > use shared_lock::{SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; >+use {Namespace, Prefix}; > > /// A `@namespace` rule. > #[derive(Clone, Debug, PartialEq)] > #[allow(missing_docs)] > pub struct NamespaceRule { > /// The namespace prefix, and `None` if it's the default Namespace > pub prefix: Option<Prefix>, > /// The actual namespace url. >diff --git a/servo/components/style/stylesheets/rule_list.rs b/servo/components/style/stylesheets/rule_list.rs >index 35edc22b3dac..280f879a77b9 100644 >--- a/servo/components/style/stylesheets/rule_list.rs >+++ b/servo/components/style/stylesheets/rule_list.rs >@@ -6,20 +6,20 @@ > > #[cfg(feature = "gecko")] > use malloc_size_of::{MallocShallowSizeOf, MallocSizeOfOps}; > use servo_arc::{Arc, RawOffsetArc}; > use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; > use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; >-use stylesheets::{CssRule, RulesMutateError}; > use stylesheets::loader::StylesheetLoader; > use stylesheets::rule_parser::{InsertRuleContext, State}; > use stylesheets::stylesheet::StylesheetContents; >+use stylesheets::{CssRule, RulesMutateError}; > > /// A list of CSS rules. > #[derive(Debug)] > pub struct CssRules(pub Vec<CssRule>); > > impl CssRules { > /// Whether this CSS rules is empty. > pub fn is_empty(&self) -> bool { >@@ -151,17 +151,21 @@ impl CssRulesHelpers for RawOffsetArc<Locked<CssRules>> { > } > > // Computes the parser state at the given index > let state = if nested { > State::Body > } else if index == 0 { > State::Start > } else { >- rules.0.get(index - 1).map(CssRule::rule_state).unwrap_or(State::Body) >+ rules >+ .0 >+ .get(index - 1) >+ .map(CssRule::rule_state) >+ .unwrap_or(State::Body) > }; > > let insert_rule_context = InsertRuleContext { > rule_list: &rules.0, > index, > }; > > // Steps 3, 4, 5, 6 >diff --git a/servo/components/style/stylesheets/rule_parser.rs b/servo/components/style/stylesheets/rule_parser.rs >index d2f9b691ad4e..58c9cd9e732e 100644 >--- a/servo/components/style/stylesheets/rule_parser.rs >+++ b/servo/components/style/stylesheets/rule_parser.rs >@@ -1,40 +1,40 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Parsing of the stylesheet contents. > >-use {Namespace, Prefix}; > use counter_style::{parse_counter_style_body, parse_counter_style_name_definition}; > use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; > use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation}; > use error_reporting::ContextualParseError; > use font_face::parse_font_face_block; > use media_queries::MediaList; > use parser::{Parse, ParserContext}; > use properties::parse_property_declaration_list; > use selector_parser::{SelectorImpl, SelectorParser}; > use selectors::SelectorList; > use servo_arc::Arc; > use shared_lock::{Locked, SharedRwLock}; > use str::starts_with_ignore_ascii_case; > use style_traits::{ParseError, StyleParseErrorKind}; >-use stylesheets::{CssRule, CssRuleType, CssRules, Origin, RulesMutateError, StylesheetLoader}; >-use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule}; >-use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule}; > use stylesheets::document_rule::DocumentCondition; > use stylesheets::font_feature_values_rule::parse_family_name_list; > use stylesheets::keyframes_rule::parse_keyframe_list; > use stylesheets::stylesheet::Namespaces; > use stylesheets::supports_rule::SupportsCondition; > use stylesheets::viewport_rule; >-use values::{CssUrl, CustomIdent, KeyframesName}; >+use stylesheets::{CssRule, CssRuleType, CssRules, Origin, RulesMutateError, StylesheetLoader}; >+use stylesheets::{DocumentRule, FontFeatureValuesRule, KeyframesRule, MediaRule}; >+use stylesheets::{NamespaceRule, PageRule, StyleRule, SupportsRule, ViewportRule}; > use values::computed::font::FamilyName; >+use values::{CssUrl, CustomIdent, KeyframesName}; >+use {Namespace, Prefix}; > > /// The information we need particularly to do CSSOM insertRule stuff. > pub struct InsertRuleContext<'a> { > /// The rule list we're about to insert into. > pub rule_list: &'a [CssRule], > /// The index we're about to get inserted at. > pub index: usize, > } >@@ -105,18 +105,19 @@ impl<'b> TopLevelRuleParser<'b> { > if new_state > next_rule_state { > self.dom_error = Some(RulesMutateError::HierarchyRequest); > return false; > } > > // If there's anything that isn't a namespace rule (or import rule, but > // we checked that already at the beginning), reject with a > // StateError. >- if new_state == State::Namespaces && >- ctx.rule_list[ctx.index..].iter().any(|r| !matches!(*r, CssRule::Namespace(..))) >+ if new_state == State::Namespaces && ctx.rule_list[ctx.index..] >+ .iter() >+ .any(|r| !matches!(*r, CssRule::Namespace(..))) > { > self.dom_error = Some(RulesMutateError::InvalidState); > return false; > } > > true > } > } >@@ -222,17 +223,17 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { > "charset" => { > self.dom_error = Some(RulesMutateError::HierarchyRequest); > return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedCharsetRule)) > } > _ => {} > } > > if !self.check_state(State::Body) { >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > > AtRuleParser::parse_prelude(&mut self.nested(), name, input) > } > > #[inline] > fn parse_block<'t>( > &mut self, >@@ -249,83 +250,81 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { > #[inline] > fn rule_without_block( > &mut self, > prelude: AtRuleNonBlockPrelude, > source_location: SourceLocation, > ) -> CssRule { > match prelude { > AtRuleNonBlockPrelude::Import(url, media) => { >- let loader = self.loader >+ let loader = self >+ .loader > .expect("Expected a stylesheet loader for @import"); > > let import_rule = loader.request_stylesheet( > url, > source_location, > &self.context, > &self.shared_lock, > media, > ); > > self.state = State::Imports; > CssRule::Import(import_rule) >- }, >+ } > AtRuleNonBlockPrelude::Namespace(prefix, url) => { > let prefix = if let Some(prefix) = prefix { > self.namespaces.prefixes.insert(prefix.clone(), url.clone()); > Some(prefix) > } else { > self.namespaces.default = Some(url.clone()); > None > }; > > self.state = State::Namespaces; > CssRule::Namespace(Arc::new(self.shared_lock.wrap(NamespaceRule { > prefix, > url, > source_location, > }))) >- }, >+ } > } > } > } > > impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> { > type Prelude = SelectorList<SelectorImpl>; > type QualifiedRule = CssRule; > type Error = StyleParseErrorKind<'i>; > > #[inline] > fn parse_prelude<'t>( > &mut self, > input: &mut Parser<'i, 't>, > ) -> Result<Self::Prelude, ParseError<'i>> { > if !self.check_state(State::Body) { >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > > QualifiedRuleParser::parse_prelude(&mut self.nested(), input) > } > > #[inline] > fn parse_block<'t>( > &mut self, > prelude: Self::Prelude, > location: SourceLocation, > input: &mut Parser<'i, 't>, > ) -> Result<CssRule, ParseError<'i>> { >- QualifiedRuleParser::parse_block( >- &mut self.nested(), >- prelude, >- location, >- input, >- ).map(|result| { >- self.state = State::Body; >- result >- }) >+ QualifiedRuleParser::parse_block(&mut self.nested(), prelude, location, input).map( >+ |result| { >+ self.state = State::Body; >+ result >+ }, >+ ) > } > } > > #[derive(Clone)] // shallow, relatively cheap .clone > struct NestedRuleParser<'a, 'b: 'a> { > stylesheet_origin: Origin, > shared_lock: &'a SharedRwLock, > context: &'a ParserContext<'b>, >@@ -333,21 +332,17 @@ struct NestedRuleParser<'a, 'b: 'a> { > } > > impl<'a, 'b> NestedRuleParser<'a, 'b> { > fn parse_nested_rules( > &mut self, > input: &mut Parser, > rule_type: CssRuleType, > ) -> Arc<Locked<CssRules>> { >- let context = ParserContext::new_with_rule_type( >- self.context, >- rule_type, >- self.namespaces, >- ); >+ let context = ParserContext::new_with_rule_type(self.context, rule_type, self.namespaces); > > let nested_parser = NestedRuleParser { > stylesheet_origin: self.stylesheet_origin, > shared_lock: self.shared_lock, > context: &context, > namespaces: self.namespaces, > }; > >@@ -355,17 +350,17 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> { > let mut rules = Vec::new(); > while let Some(result) = iter.next() { > match result { > Ok(rule) => rules.push(rule), > Err((error, slice)) => { > let location = error.location; > let error = ContextualParseError::InvalidRule(slice, error); > self.context.log_css_error(location, error); >- }, >+ } > } > } > CssRules::new(rules, self.shared_lock) > } > } > > impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { > type PreludeNoBlock = AtRuleNonBlockPrelude; >@@ -464,132 +459,115 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> { > self.context, > CssRuleType::FontFace, > self.namespaces, > ); > > Ok(CssRule::FontFace(Arc::new(self.shared_lock.wrap( > parse_font_face_block(&context, input, source_location).into(), > )))) >- }, >+ } > AtRuleBlockPrelude::FontFeatureValues(family_names) => { > let context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::FontFeatureValues, > self.namespaces, > ); > > Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap( >- FontFeatureValuesRule::parse( >- &context, >- input, >- family_names, >- source_location, >- ), >+ FontFeatureValuesRule::parse(&context, input, family_names, source_location), > )))) >- }, >+ } > AtRuleBlockPrelude::CounterStyle(name) => { > let context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::CounterStyle, > self.namespaces, > ); > >- Ok(CssRule::CounterStyle(Arc::new( >- self.shared_lock.wrap( >- parse_counter_style_body( >- name, >- &context, >- input, >- source_location, >- )?.into(), >- ), >- ))) >- }, >+ Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap( >+ parse_counter_style_body(name, &context, input, source_location)?.into(), >+ )))) >+ } > AtRuleBlockPrelude::Media(media_queries) => { > Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule { > media_queries, > rules: self.parse_nested_rules(input, CssRuleType::Media), > source_location, > })))) >- }, >+ } > AtRuleBlockPrelude::Supports(condition) => { > let eval_context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::Style, > self.namespaces, > ); > > let enabled = condition.eval(&eval_context); > Ok(CssRule::Supports(Arc::new(self.shared_lock.wrap( > SupportsRule { > condition, > rules: self.parse_nested_rules(input, CssRuleType::Supports), > enabled, > source_location, > }, > )))) >- }, >+ } > AtRuleBlockPrelude::Viewport => { > let context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::Viewport, > self.namespaces, > ); > >- Ok(CssRule::Viewport(Arc::new(self.shared_lock.wrap( >- ViewportRule::parse(&context, input)?, >- )))) >- }, >+ Ok(CssRule::Viewport(Arc::new( >+ self.shared_lock.wrap(ViewportRule::parse(&context, input)?), >+ ))) >+ } > AtRuleBlockPrelude::Keyframes(name, vendor_prefix) => { > let context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::Keyframes, > self.namespaces, > ); > > Ok(CssRule::Keyframes(Arc::new(self.shared_lock.wrap( > KeyframesRule { > name, >- keyframes: parse_keyframe_list( >- &context, >- input, >- self.shared_lock, >- ), >+ keyframes: parse_keyframe_list(&context, input, self.shared_lock), > vendor_prefix, > source_location, > }, > )))) >- }, >+ } > AtRuleBlockPrelude::Page => { > let context = ParserContext::new_with_rule_type( > self.context, > CssRuleType::Page, > self.namespaces, > ); > >- let declarations = >- parse_property_declaration_list(&context, input); >+ let declarations = parse_property_declaration_list(&context, input); > Ok(CssRule::Page(Arc::new(self.shared_lock.wrap(PageRule { > block: Arc::new(self.shared_lock.wrap(declarations)), > source_location, > })))) >- }, >+ } > AtRuleBlockPrelude::Document(condition) => { > if !cfg!(feature = "gecko") { > unreachable!() > } > Ok(CssRule::Document(Arc::new(self.shared_lock.wrap( > DocumentRule { > condition, > rules: self.parse_nested_rules(input, CssRuleType::Document), > source_location, > }, > )))) >- }, >+ } > } > } > } > > impl<'a, 'b, 'i> QualifiedRuleParser<'i> for NestedRuleParser<'a, 'b> { > type Prelude = SelectorList<SelectorImpl>; > type QualifiedRule = CssRule; > type Error = StyleParseErrorKind<'i>; >diff --git a/servo/components/style/stylesheets/rules_iterator.rs b/servo/components/style/stylesheets/rules_iterator.rs >index b46e24c22c72..a93532750cbd 100644 >--- a/servo/components/style/stylesheets/rules_iterator.rs >+++ b/servo/components/style/stylesheets/rules_iterator.rs >@@ -4,18 +4,18 @@ > > //! An iterator over a list of rules. > > use context::QuirksMode; > use media_queries::Device; > use shared_lock::SharedRwLockReadGuard; > use smallvec::SmallVec; > use std::slice; >-use stylesheets::{CssRule, DocumentRule, ImportRule, MediaRule, SupportsRule}; > use stylesheets::StylesheetInDocument; >+use stylesheets::{CssRule, DocumentRule, ImportRule, MediaRule, SupportsRule}; > > /// An iterator over a list of rules. > pub struct RulesIterator<'a, 'b, C> > where > 'b: 'a, > C: NestedRuleIterationCondition + 'static, > { > device: &'a Device, >@@ -73,71 +73,68 @@ where > let rule; > let sub_iter = { > let nested_iter = self.stack.last_mut().unwrap(); > rule = match nested_iter.next() { > Some(r) => r, > None => { > nested_iter_finished = true; > continue; >- }, >+ } > }; > > match *rule { >- CssRule::Namespace(_) | >- CssRule::Style(_) | >- CssRule::FontFace(_) | >- CssRule::CounterStyle(_) | >- CssRule::Viewport(_) | >- CssRule::Keyframes(_) | >- CssRule::Page(_) | >- CssRule::FontFeatureValues(_) => return Some(rule), >+ CssRule::Namespace(_) >+ | CssRule::Style(_) >+ | CssRule::FontFace(_) >+ | CssRule::CounterStyle(_) >+ | CssRule::Viewport(_) >+ | CssRule::Keyframes(_) >+ | CssRule::Page(_) >+ | CssRule::FontFeatureValues(_) => return Some(rule), > CssRule::Import(ref import_rule) => { > let import_rule = import_rule.read_with(self.guard); > if !C::process_import( > self.guard, > self.device, > self.quirks_mode, > import_rule, > ) { > continue; > } >- import_rule >- .stylesheet >- .rules(self.guard) >- .iter() >- }, >+ import_rule.stylesheet.rules(self.guard).iter() >+ } > CssRule::Document(ref doc_rule) => { > let doc_rule = doc_rule.read_with(self.guard); > if !C::process_document(self.guard, self.device, self.quirks_mode, doc_rule) > { > continue; > } > doc_rule.rules.read_with(self.guard).0.iter() >- }, >+ } > CssRule::Media(ref lock) => { > let media_rule = lock.read_with(self.guard); > if !C::process_media(self.guard, self.device, self.quirks_mode, media_rule) > { > continue; > } > media_rule.rules.read_with(self.guard).0.iter() >- }, >+ } > CssRule::Supports(ref lock) => { > let supports_rule = lock.read_with(self.guard); > if !C::process_supports( > self.guard, > self.device, > self.quirks_mode, > supports_rule, > ) { > continue; > } > supports_rule.rules.read_with(self.guard).0.iter() >- }, >+ } > } > }; > > self.stack.push(sub_iter); > return Some(rule); > } > > None >diff --git a/servo/components/style/stylesheets/style_rule.rs b/servo/components/style/stylesheets/style_rule.rs >index c161cc43ee21..90cc6eb8b6e6 100644 >--- a/servo/components/style/stylesheets/style_rule.rs >+++ b/servo/components/style/stylesheets/style_rule.rs >@@ -1,19 +1,19 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! A style rule. > > use cssparser::SourceLocation; > #[cfg(feature = "gecko")] >-use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; >-#[cfg(feature = "gecko")] > use malloc_size_of::MallocUnconditionalShallowSizeOf; >+#[cfg(feature = "gecko")] >+use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; > use properties::PropertyDeclarationBlock; > use selector_parser::SelectorImpl; > use selectors::SelectorList; > use servo_arc::Arc; > use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; > use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; > use std::fmt::{self, Write}; > use str::CssStringWriter; >@@ -46,18 +46,18 @@ impl DeepCloneWithLock for StyleRule { > } > > impl StyleRule { > /// Measure heap usage. > #[cfg(feature = "gecko")] > pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { > let mut n = 0; > n += self.selectors.0.size_of(ops); >- n += self.block.unconditional_shallow_size_of(ops) + >- self.block.read_with(guard).size_of(ops); >+ n += self.block.unconditional_shallow_size_of(ops) >+ + self.block.read_with(guard).size_of(ops); > n > } > } > > impl ToCssWithGuard for StyleRule { > /// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > use cssparser::ToCss; >diff --git a/servo/components/style/stylesheets/stylesheet.rs b/servo/components/style/stylesheets/stylesheet.rs >index 02730f7090d5..68419d0ca74a 100644 >--- a/servo/components/style/stylesheets/stylesheet.rs >+++ b/servo/components/style/stylesheets/stylesheet.rs >@@ -1,34 +1,36 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > >-use {Namespace, Prefix}; > use context::QuirksMode; > use cssparser::{Parser, ParserInput, RuleListParser}; > use error_reporting::{ContextualParseError, ParseErrorReporter}; > use fallible::FallibleVec; > use fxhash::FxHashMap; > use invalidation::media_queries::{MediaListKey, ToMediaListKey}; > #[cfg(feature = "gecko")] > use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; > use media_queries::{Device, MediaList}; > use parking_lot::RwLock; > use parser::ParserContext; > use servo_arc::Arc; >-use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard}; >+use shared_lock::{ >+ DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, >+}; > use std::mem; > use std::sync::atomic::{AtomicBool, Ordering}; > use style_traits::ParsingMode; >-use stylesheets::{CssRule, CssRules, Origin, UrlExtraData}; > use stylesheets::loader::StylesheetLoader; > use stylesheets::rule_parser::{State, TopLevelRuleParser}; > use stylesheets::rules_iterator::{EffectiveRules, EffectiveRulesIterator}; > use stylesheets::rules_iterator::{NestedRuleIterationCondition, RulesIterator}; >+use stylesheets::{CssRule, CssRules, Origin, UrlExtraData}; >+use {Namespace, Prefix}; > > /// This structure holds the user-agent and user stylesheets. > pub struct UserAgentStylesheets { > /// The lock used for user-agent stylesheets. > pub shared_lock: SharedRwLock, > /// The user or user agent stylesheets. > pub user_or_user_agent_stylesheets: Vec<DocumentStyleSheet>, > /// The quirks mode stylesheet. >@@ -108,30 +110,31 @@ impl StylesheetContents { > pub fn rules<'a, 'b: 'a>(&'a self, guard: &'b SharedRwLockReadGuard) -> &'a [CssRule] { > &self.rules.read_with(guard).0 > } > > /// Measure heap usage. > #[cfg(feature = "gecko")] > pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { > // Measurement of other fields may be added later. >- self.rules.unconditional_shallow_size_of(ops) + >- self.rules.read_with(guard).size_of(guard, ops) >+ self.rules.unconditional_shallow_size_of(ops) >+ + self.rules.read_with(guard).size_of(guard, ops) > } > } > > impl DeepCloneWithLock for StylesheetContents { > fn deep_clone_with_lock( > &self, > lock: &SharedRwLock, > guard: &SharedRwLockReadGuard, > params: &DeepCloneParams, > ) -> Self { > // Make a deep clone of the rules, using the new lock. >- let rules = self.rules >+ let rules = self >+ .rules > .read_with(guard) > .deep_clone_with_lock(lock, guard, params); > > Self { > rules: Arc::new(lock.wrap(rules)), > quirks_mode: self.quirks_mode, > origin: self.origin, > url_data: RwLock::new((*self.url_data.read()).clone()), >@@ -171,17 +174,17 @@ macro_rules! rule_filter { > } > } > } > )+ > } > } > > /// A trait to represent a given stylesheet in a document. >-pub trait StylesheetInDocument : ::std::fmt::Debug { >+pub trait StylesheetInDocument: ::std::fmt::Debug { > /// Get the stylesheet origin. > fn origin(&self, guard: &SharedRwLockReadGuard) -> Origin; > > /// Get the stylesheet quirks mode. > fn quirks_mode(&self, guard: &SharedRwLockReadGuard) -> QuirksMode; > > /// Get whether this stylesheet is enabled. > fn enabled(&self) -> bool; >@@ -382,25 +385,22 @@ impl Stylesheet { > match result { > Ok(rule) => { > // Use a fallible push here, and if it fails, just > // fall out of the loop. This will cause the page to > // be shown incorrectly, but it's better than OOMing. > if rules.try_push(rule).is_err() { > break; > } >- }, >+ } > Err((error, slice)) => { > let location = error.location; > let error = ContextualParseError::InvalidRule(slice, error); >- iter.parser.context.log_css_error( >- location, >- error, >- ); >- }, >+ iter.parser.context.log_css_error(location, error); >+ } > } > } > } > > let source_map_url = input.current_source_map_url().map(String::from); > let source_url = input.current_source_url().map(String::from); > (rules, source_map_url, source_url) > } >@@ -463,17 +463,18 @@ impl Clone for Stylesheet { > fn clone(&self) -> Self { > // Create a new lock for our clone. > let lock = self.shared_lock.clone(); > let guard = self.shared_lock.read(); > > // Make a deep clone of the media, using the new lock. > let media = self.media.read_with(&guard).clone(); > let media = Arc::new(lock.wrap(media)); >- let contents = self.contents >+ let contents = self >+ .contents > .deep_clone_with_lock(&lock, &guard, &DeepCloneParams); > > Stylesheet { > contents, > media: media, > shared_lock: lock, > disabled: AtomicBool::new(self.disabled.load(Ordering::SeqCst)), > } >diff --git a/servo/components/style/stylesheets/supports_rule.rs b/servo/components/style/stylesheets/supports_rule.rs >index f8c3235f2952..1223a55adc0f 100644 >--- a/servo/components/style/stylesheets/supports_rule.rs >+++ b/servo/components/style/stylesheets/supports_rule.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! [@supports rules](https://drafts.csswg.org/css-conditional-3/#at-supports) > >+use cssparser::parse_important; > use cssparser::{Delimiter, Parser, SourceLocation, Token}; > use cssparser::{ParseError as CssParseError, ParserInput}; >-use cssparser::parse_important; > #[cfg(feature = "gecko")] > use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; > use parser::ParserContext; > use properties::{PropertyDeclaration, PropertyId, SourcePropertyDeclaration}; > use selectors::parser::SelectorParseErrorKind; > use servo_arc::Arc; > use shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; > use shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; >@@ -37,18 +37,18 @@ pub struct SupportsRule { > pub source_location: SourceLocation, > } > > impl SupportsRule { > /// Measure heap usage. > #[cfg(feature = "gecko")] > pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { > // Measurement of other fields may be added later. >- self.rules.unconditional_shallow_size_of(ops) + >- self.rules.read_with(guard).size_of(guard, ops) >+ self.rules.unconditional_shallow_size_of(ops) >+ + self.rules.read_with(guard).size_of(guard, ops) > } > } > > impl ToCssWithGuard for SupportsRule { > fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { > dest.write_str("@supports ")?; > self.condition.to_css(&mut CssWriter::new(dest))?; > self.rules.read_with(guard).to_css_block(guard, dest) >@@ -107,24 +107,24 @@ impl SupportsCondition { > > let in_parens = SupportsCondition::parse_in_parens(input)?; > > let location = input.current_source_location(); > let (keyword, wrapper) = match input.next() { > Err(_) => { > // End of input > return Ok(in_parens); >- }, >+ } > Ok(&Token::Ident(ref ident)) => { > match_ignore_ascii_case! { &ident, > "and" => ("and", SupportsCondition::And as fn(_) -> _), > "or" => ("or", SupportsCondition::Or as fn(_) -> _), > _ => return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) > } >- }, >+ } > Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), > }; > > let mut conditions = Vec::with_capacity(2); > conditions.push(in_parens); > loop { > conditions.push(SupportsCondition::parse_in_parens(input)?); > if input >@@ -151,36 +151,34 @@ impl SupportsCondition { > // FIXME: remove clone() when lifetimes are non-lexical > match input.next()?.clone() { > Token::ParenthesisBlock => { > let nested = input > .try(|input| input.parse_nested_block(|i| parse_condition_or_declaration(i))); > if nested.is_ok() { > return nested; > } >- }, >+ } > Token::Function(ident) => { > // Although this is an internal syntax, it is not necessary to check > // parsing context as far as we accept any unexpected token as future > // syntax, and evaluate it to false when not in chrome / ua sheet. > // See https://drafts.csswg.org/css-conditional-3/#general_enclosed > if ident.eq_ignore_ascii_case("-moz-bool-pref") { > if let Ok(name) = input.try(|i| { > i.parse_nested_block(|i| { > i.expect_string() > .map(|s| s.to_string()) > .map_err(CssParseError::<()>::from) >- }).and_then(|s| { >- CString::new(s).map_err(|_| location.new_custom_error(())) >- }) >+ }).and_then(|s| CString::new(s).map_err(|_| location.new_custom_error(()))) > }) { > return Ok(SupportsCondition::MozBoolPref(name)); > } > } >- }, >+ } > t => return Err(location.new_unexpected_token_error(t)), > } > input.parse_nested_block(|i| consume_any_value(i))?; > Ok(SupportsCondition::FutureSyntax( > input.slice_from(pos).to_owned(), > )) > } > >@@ -229,56 +227,56 @@ impl ToCss for SupportsCondition { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > match *self { > SupportsCondition::Not(ref cond) => { > dest.write_str("not ")?; > cond.to_css(dest) >- }, >+ } > SupportsCondition::Parenthesized(ref cond) => { > dest.write_str("(")?; > cond.to_css(dest)?; > dest.write_str(")") >- }, >+ } > SupportsCondition::And(ref vec) => { > let mut first = true; > for cond in vec { > if !first { > dest.write_str(" and ")?; > } > first = false; > cond.to_css(dest)?; > } > Ok(()) >- }, >+ } > SupportsCondition::Or(ref vec) => { > let mut first = true; > for cond in vec { > if !first { > dest.write_str(" or ")?; > } > first = false; > cond.to_css(dest)?; > } > Ok(()) >- }, >+ } > SupportsCondition::Declaration(ref decl) => { > dest.write_str("(")?; > decl.to_css(dest)?; > dest.write_str(")") >- }, >+ } > SupportsCondition::MozBoolPref(ref name) => { > dest.write_str("-moz-bool-pref(")?; > let name = > str::from_utf8(name.as_bytes()).expect("Should be parsed from valid UTF-8"); > name.to_css(dest)?; > dest.write_str(")") >- }, >+ } > SupportsCondition::FutureSyntax(ref s) => dest.write_str(&s), > } > } > } > > #[derive(Clone, Debug)] > /// A possibly-invalid property declaration > pub struct Declaration(pub String); >@@ -310,29 +308,26 @@ impl Declaration { > /// Determine if a declaration parses > /// > /// <https://drafts.csswg.org/css-conditional-3/#support-definition> > pub fn eval(&self, context: &ParserContext) -> bool { > debug_assert_eq!(context.rule_type(), CssRuleType::Style); > > let mut input = ParserInput::new(&self.0); > let mut input = Parser::new(&mut input); >- input.parse_entirely(|input| -> Result<(), CssParseError<()>> { >- let prop = input.expect_ident_cloned().unwrap(); >- input.expect_colon().unwrap(); >+ input >+ .parse_entirely(|input| -> Result<(), CssParseError<()>> { >+ let prop = input.expect_ident_cloned().unwrap(); >+ input.expect_colon().unwrap(); > >- let id = PropertyId::parse(&prop, context) >- .map_err(|_| input.new_custom_error(()))?; >+ let id = >+ PropertyId::parse(&prop, context).map_err(|_| input.new_custom_error(()))?; > >- let mut declarations = SourcePropertyDeclaration::new(); >- input.parse_until_before(Delimiter::Bang, |input| { >- PropertyDeclaration::parse_into( >- &mut declarations, >- id, >- &context, >- input, >- ).map_err(|_| input.new_custom_error(())) >- })?; >- let _ = input.try(parse_important); >- Ok(()) >- }).is_ok() >+ let mut declarations = SourcePropertyDeclaration::new(); >+ input.parse_until_before(Delimiter::Bang, |input| { >+ PropertyDeclaration::parse_into(&mut declarations, id, &context, input) >+ .map_err(|_| input.new_custom_error(())) >+ })?; >+ let _ = input.try(parse_important); >+ Ok(()) >+ }).is_ok() > } > } >diff --git a/servo/components/style/stylesheets/viewport_rule.rs b/servo/components/style/stylesheets/viewport_rule.rs >index 1fc6a988c7ca..30848743ba67 100644 >--- a/servo/components/style/stylesheets/viewport_rule.rs >+++ b/servo/components/style/stylesheets/viewport_rule.rs >@@ -4,35 +4,35 @@ > > //! The [`@viewport`][at] at-rule and [`meta`][meta] element. > //! > //! [at]: https://drafts.csswg.org/css-device-adapt/#atviewport-rule > //! [meta]: https://drafts.csswg.org/css-device-adapt/#viewport-meta > > use app_units::Au; > use context::QuirksMode; >-use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; > use cssparser::CowRcStr; >+use cssparser::{parse_important, AtRuleParser, DeclarationListParser, DeclarationParser, Parser}; > use error_reporting::ContextualParseError; > use euclid::TypedSize2D; > use font_metrics::get_metrics_provider_for_product; > use media_queries::Device; > use parser::ParserContext; > use properties::StyleBuilder; > use rule_cache::RuleCacheConditions; > use selectors::parser::SelectorParseErrorKind; > use shared_lock::{SharedRwLockReadGuard, StylesheetGuards, ToCssWithGuard}; > use std::borrow::Cow; > use std::cell::RefCell; > use std::fmt::{self, Write}; > use std::iter::Enumerate; > use std::str::Chars; > use str::CssStringWriter; >-use style_traits::{CssWriter, ParseError, PinchZoomFactor, StyleParseErrorKind, ToCss}; > use style_traits::viewport::{Orientation, UserZoom, ViewportConstraints, Zoom}; >+use style_traits::{CssWriter, ParseError, PinchZoomFactor, StyleParseErrorKind, ToCss}; > use stylesheets::{Origin, StylesheetInDocument}; > use values::computed::{Context, ToComputedValue}; > use values::specified::{LengthOrPercentageOrAuto, NoCalcLength, ViewportPercentageLength}; > > /// Whether parsing and processing of `@viewport` rules is enabled. > #[cfg(feature = "servo")] > pub fn enabled() -> bool { > use servo_config::prefs::PREFS; >@@ -366,25 +366,24 @@ impl ViewportRule { > let mut cascade = Cascade::new(); > let mut parser = DeclarationListParser::new(input, parser); > while let Some(result) = parser.next() { > match result { > Ok(declarations) => { > for declarations in declarations { > cascade.add(Cow::Owned(declarations)) > } >- }, >+ } > Err((error, slice)) => { > let location = error.location; > let error = ContextualParseError::UnsupportedViewportDescriptorDeclaration( >- slice, >- error, >+ slice, error, > ); > context.log_css_error(location, error); >- }, >+ } > } > } > Ok(ViewportRule { > declarations: cascade.finish(), > }) > } > } > >@@ -433,36 +432,36 @@ impl ViewportRule { > > match name { > n if n.eq_ignore_ascii_case("width") => { > if let Some(value) = ViewportLength::from_meta(value) { > push_descriptor!(MinWidth(ViewportLength::ExtendToZoom)); > push_descriptor!(MaxWidth(value)); > has_width = true; > } >- }, >+ } > n if n.eq_ignore_ascii_case("height") => { > if let Some(value) = ViewportLength::from_meta(value) { > push_descriptor!(MinHeight(ViewportLength::ExtendToZoom)); > push_descriptor!(MaxHeight(value)); > has_height = true; > } >- }, >+ } > n if n.eq_ignore_ascii_case("initial-scale") => { > if let Some(value) = Zoom::from_meta(value) { > push_descriptor!(Zoom(value)); > has_zoom = true; > } >- }, >+ } > n if n.eq_ignore_ascii_case("minimum-scale") => push!(MinZoom(Zoom::from_meta)), > n if n.eq_ignore_ascii_case("maximum-scale") => push!(MaxZoom(Zoom::from_meta)), > n if n.eq_ignore_ascii_case("user-scalable") => { > push!(UserZoom(UserZoom::from_meta)) >- }, >- _ => {}, >+ } >+ _ => {} > } > } > } > > // DEVICE-ADAPT § 9.4 - The 'width' and 'height' properties > // http://dev.w3.org/csswg/css-device-adapt/#width-and-height-properties > if !has_width && has_zoom { > if has_height { >@@ -605,20 +604,20 @@ impl Cascade { > let descriptor = declaration.descriptor.discriminant_value(); > > match self.declarations[descriptor] { > Some((ref mut order_of_appearance, ref mut entry_declaration)) => { > if declaration.higher_or_equal_precendence(entry_declaration) { > *entry_declaration = declaration.into_owned(); > *order_of_appearance = self.count_so_far; > } >- }, >+ } > ref mut entry @ None => { > *entry = Some((self.count_so_far, declaration.into_owned())); >- }, >+ } > } > self.count_so_far += 1; > } > > pub fn finish(mut self) -> Vec<ViewportDescriptorDeclaration> { > // sort the descriptors by order of appearance > self.declarations > .sort_by_key(|entry| entry.as_ref().map(|&(index, _)| index)); >@@ -750,34 +749,34 @@ impl MaybeNew for ViewportConstraints { > > macro_rules! to_pixel_length { > ($value:ident, $dimension:ident, $extend_to:ident => $auto_extend_to:expr) => { > if let Some($value) = $value { > match *$value { > ViewportLength::Specified(ref length) => match *length { > LengthOrPercentageOrAuto::Length(ref value) => { > Some(Au::from(value.to_computed_value(&context))) >- }, >+ } > LengthOrPercentageOrAuto::Percentage(value) => { > Some(initial_viewport.$dimension.scale_by(value.0)) >- }, >+ } > LengthOrPercentageOrAuto::Auto => None, >- LengthOrPercentageOrAuto::Calc(ref calc) => calc.to_computed_value( >- &context, >- ).to_used_value(Some(initial_viewport.$dimension)), >+ LengthOrPercentageOrAuto::Calc(ref calc) => calc >+ .to_computed_value(&context) >+ .to_used_value(Some(initial_viewport.$dimension)), > }, > ViewportLength::ExtendToZoom => { > // $extend_to will be 'None' if 'extend-to-zoom' is 'auto' > match ($extend_to, $auto_extend_to) { > (None, None) => None, > (a, None) => a, > (None, b) => b, > (a, b) => cmp::max(a, b), > } >- }, >+ } > } > } else { > None > } > }; > } > > // DEVICE-ADAPT § 9.3 states that max-descriptors need to be resolved >@@ -818,26 +817,26 @@ impl MaybeNew for ViewportConstraints { > width > }; > > let width = width.unwrap_or_else(|| match initial_viewport.height { > Au(0) => initial_viewport.width, > initial_height => { > let ratio = initial_viewport.width.to_f32_px() / initial_height.to_f32_px(); > Au::from_f32_px(height.unwrap().to_f32_px() * ratio) >- }, >+ } > }); > > // DEVICE-ADAPT § 6.2.6 Resolve height value > let height = height.unwrap_or_else(|| match initial_viewport.width { > Au(0) => initial_viewport.height, > initial_width => { > let ratio = initial_viewport.height.to_f32_px() / initial_width.to_f32_px(); > Au::from_f32_px(width.to_f32_px() * ratio) >- }, >+ } > }); > > Some(ViewportConstraints { > size: TypedSize2D::new(width.to_f32_px(), height.to_f32_px()), > > // TODO: compute a zoom factor for 'auto' as suggested by DEVICE-ADAPT § 10. > initial_zoom: PinchZoomFactor::new(initial_zoom.unwrap_or(1.)), > min_zoom: min_zoom.map(PinchZoomFactor::new), >diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs >index dbddca725e12..7f8690500e67 100644 >--- a/servo/components/style/stylist.rs >+++ b/servo/components/style/stylist.rs >@@ -1,61 +1,61 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Selector matching. > >-use {Atom, LocalName, Namespace, WeakAtom}; > use applicable_declarations::{ApplicableDeclarationBlock, ApplicableDeclarationList}; > use context::{CascadeInputs, QuirksMode}; > use dom::{TElement, TShadowRoot}; > use element_state::{DocumentState, ElementState}; > use font_metrics::FontMetricsProvider; > #[cfg(feature = "gecko")] > use gecko_bindings::structs::{ServoStyleSetSizes, StyleRuleInclusion}; > use hashglobe::FailedAllocationError; > use invalidation::element::invalidation_map::InvalidationMap; > use invalidation::media_queries::{EffectiveMediaQueryResults, ToMediaListKey}; > #[cfg(feature = "gecko")] >-use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; >-#[cfg(feature = "gecko")] > use malloc_size_of::MallocUnconditionalShallowSizeOf; >+#[cfg(feature = "gecko")] >+use malloc_size_of::{MallocShallowSizeOf, MallocSizeOf, MallocSizeOfOps}; > use media_queries::Device; > use properties::{self, CascadeMode, ComputedValues}; > use properties::{AnimationRules, PropertyDeclarationBlock}; > use rule_cache::{RuleCache, RuleCacheConditions}; > use rule_tree::{CascadeLevel, RuleTree, ShadowCascadeOrder, StrongRuleNode, StyleSource}; > use selector_map::{PrecomputedHashMap, SelectorMap, SelectorMapEntry}; > use selector_parser::{PerPseudoElementMap, PseudoElement, SelectorImpl, SnapshotMap}; >-use selectors::NthIndexCache; > use selectors::attr::{CaseSensitivity, NamespaceConstraint}; > use selectors::bloom::{BloomFilter, NonCountingBloomFilter}; >-use selectors::matching::{matches_selector, ElementSelectorFlags, MatchingContext, MatchingMode}; > use selectors::matching::VisitedHandlingMode; >+use selectors::matching::{matches_selector, ElementSelectorFlags, MatchingContext, MatchingMode}; > use selectors::parser::{AncestorHashes, Combinator, Component, Selector}; > use selectors::parser::{SelectorIter, Visit}; > use selectors::visitor::SelectorVisitor; >+use selectors::NthIndexCache; > use servo_arc::{Arc, ArcBorrow}; > use shared_lock::{Locked, SharedRwLockReadGuard, StylesheetGuards}; > use smallbitvec::SmallBitVec; > use smallvec::SmallVec; > use std::ops; > use std::sync::Mutex; > use style_traits::viewport::ViewportConstraints; > use stylesheet_set::{DataValidity, DocumentStylesheetSet, SheetRebuildKind}; > use stylesheet_set::{DocumentStylesheetFlusher, SheetCollectionFlusher}; >-#[cfg(feature = "gecko")] >-use stylesheets::{CounterStyleRule, FontFaceRule, FontFeatureValuesRule, PageRule}; >-use stylesheets::{CssRule, Origin, OriginSet, PerOrigin, PerOriginIter}; >-use stylesheets::StyleRule; >-use stylesheets::StylesheetInDocument; > use stylesheets::keyframes_rule::KeyframesAnimation; > use stylesheets::viewport_rule::{self, MaybeNew, ViewportRule}; >+use stylesheets::StyleRule; >+use stylesheets::StylesheetInDocument; >+#[cfg(feature = "gecko")] >+use stylesheets::{CounterStyleRule, FontFaceRule, FontFeatureValuesRule, PageRule}; >+use stylesheets::{CssRule, Origin, OriginSet, PerOrigin, PerOriginIter}; > use thread_state::{self, ThreadState}; >+use {Atom, LocalName, Namespace, WeakAtom}; > > /// The type of the stylesheets that the stylist contains. > #[cfg(feature = "servo")] > pub type StylistSheet = ::stylesheets::DocumentStyleSheet; > > /// The type of the stylesheets that the stylist contains. > #[cfg(feature = "gecko")] > pub type StylistSheet = ::gecko::data::GeckoStyleSheet; >@@ -179,18 +179,20 @@ impl UserAgentCascadeData { > sizes.mPrecomputedPseudos += self.precomputed_pseudo_element_decls.size_of(ops); > } > } > > /// All the computed information for a stylesheet. > #[derive(Default)] > #[cfg_attr(feature = "servo", derive(MallocSizeOf))] > struct DocumentCascadeData { >- #[cfg_attr(feature = "servo", >- ignore_malloc_size_of = "Arc, owned by UserAgentCascadeDataCache")] >+ #[cfg_attr( >+ feature = "servo", >+ ignore_malloc_size_of = "Arc, owned by UserAgentCascadeDataCache" >+ )] > user_agent: Arc<UserAgentCascadeData>, > user: CascadeData, > author: CascadeData, > per_origin: PerOrigin<()>, > } > > /// An iterator over the cascade data of a given document. > pub struct DocumentCascadeDataIter<'a> { >@@ -345,17 +347,20 @@ pub struct Stylist { > > /// Viewport constraints based on the current device. > viewport_constraints: Option<ViewportConstraints>, > > /// The list of stylesheets. > stylesheets: StylistStylesheetSet, > > /// If true, the quirks-mode stylesheet is applied. >- #[cfg_attr(feature = "servo", ignore_malloc_size_of = "defined in selectors")] >+ #[cfg_attr( >+ feature = "servo", >+ ignore_malloc_size_of = "defined in selectors" >+ )] > quirks_mode: QuirksMode, > > /// Selector maps for all of the style sheets in the stylist, after > /// evalutaing media rules against the current device, split out per > /// cascade level. > cascade_data: DocumentCascadeData, > > /// Whether author styles are enabled. >@@ -676,27 +681,28 @@ impl Stylist { > /// argument. This is useful for providing extra @page rules. > pub fn rule_node_for_precomputed_pseudo( > &self, > guards: &StylesheetGuards, > pseudo: &PseudoElement, > extra_declarations: Option<Vec<ApplicableDeclarationBlock>>, > ) -> StrongRuleNode { > let mut decl; >- let declarations = match self.cascade_data >+ let declarations = match self >+ .cascade_data > .user_agent > .precomputed_pseudo_element_decls > .get(pseudo) > { > Some(declarations) => match extra_declarations { > Some(mut extra_decls) => { > decl = declarations.clone(); > decl.append(&mut extra_decls); > Some(&decl) >- }, >+ } > None => Some(declarations), > }, > None => extra_declarations.as_ref(), > }; > > match declarations { > Some(decls) => self.rule_tree.insert_ordered_rules_with_important( > decls.into_iter().map(|a| a.clone().for_rule_tree()), >@@ -1131,17 +1137,18 @@ impl Stylist { > > let rule_hash_target = element.rule_hash_target(); > > let matches_user_rules = rule_hash_target.matches_user_and_author_rules(); > let matches_author_rules = > matches_user_rules && self.author_styles_enabled == AuthorStylesEnabled::Yes; > > // Normal user-agent rules. >- if let Some(map) = self.cascade_data >+ if let Some(map) = self >+ .cascade_data > .user_agent > .cascade_data > .normal_rules(pseudo_element) > { > map.get_all_matching_rules( > element, > rule_hash_target, > applicable_declarations, >@@ -1282,18 +1289,17 @@ impl Stylist { > // See: https://github.com/w3c/svgwg/issues/504 > // > // Note that we always resolve URLs against the document, so we > // can't get into a nested shadow situation here. > // > // See: https://github.com/w3c/svgwg/issues/505 > // > let host_is_svg_use = >- host.is_svg_element() && >- host.local_name() == &*local_name!("use"); >+ host.is_svg_element() && host.local_name() == &*local_name!("use"); > > match_document_author_rules = host_is_svg_use; > } > } > > // FIXME(emilio): This doesn't account for the author_styles_enabled > // stuff... > let cut_xbl_binding_inheritance = >@@ -1387,39 +1393,35 @@ impl Stylist { > pub fn may_have_rules_for_id<E>(&self, id: &WeakAtom, element: E) -> bool > where > E: TElement, > { > // If id needs to be compared case-insensitively, the logic below > // wouldn't work. Just conservatively assume it may have such rules. > match self.quirks_mode().classes_and_ids_case_sensitivity() { > CaseSensitivity::AsciiCaseInsensitive => return true, >- CaseSensitivity::CaseSensitive => {}, >+ CaseSensitivity::CaseSensitive => {} > } > > let hash = id.get_hash(); > self.any_applicable_rule_data(element, |data| data.mapped_ids.might_contain_hash(hash)) > } > > /// Returns the registered `@keyframes` animation for the specified name. > #[inline] >- pub fn get_animation<'a, E>( >- &'a self, >- name: &Atom, >- element: E, >- ) -> Option<&'a KeyframesAnimation> >+ pub fn get_animation<'a, E>(&'a self, name: &Atom, element: E) -> Option<&'a KeyframesAnimation> > where > E: TElement + 'a, > { > macro_rules! try_find_in { > ($data:expr) => { > if let Some(animation) = $data.animations.get(name) { > return Some(animation); > } >- } >+ }; > } > > // NOTE(emilio): We implement basically what Blink does for this case, > // which is [1] as of this writing. > // > // See [2] for the spec discussion about what to do about this. WebKit's > // behavior makes a bit more sense off-hand, but it's way more complex > // to implement, and it makes value computation having to thread around >@@ -1533,37 +1535,41 @@ impl Stylist { > ) -> Arc<ComputedValues> > where > E: TElement, > { > use font_metrics::get_metrics_provider_for_product; > > let block = declarations.read_with(guards.author); > let iter_declarations = || { >- block.declaration_importance_iter().map(|(declaration, importance)| { >- debug_assert!(!importance.important()); >- (declaration, CascadeLevel::StyleAttributeNormal) >- }) >+ block >+ .declaration_importance_iter() >+ .map(|(declaration, importance)| { >+ debug_assert!(!importance.important()); >+ (declaration, CascadeLevel::StyleAttributeNormal) >+ }) > }; > > let metrics = get_metrics_provider_for_product(); > > // We don't bother inserting these declarations in the rule tree, since > // it'd be quite useless and slow. > properties::apply_declarations::<E, _, _>( > &self.device, > /* pseudo = */ None, > self.rule_tree.root(), > guards, > iter_declarations, > Some(parent_style), > Some(parent_style), > Some(parent_style), > &metrics, >- CascadeMode::Unvisited { visited_rules: None }, >+ CascadeMode::Unvisited { >+ visited_rules: None, >+ }, > self.quirks_mode, > /* rule_cache = */ None, > &mut Default::default(), > /* element = */ None, > ) > } > > /// Accessor for a shared reference to the device. >@@ -1689,18 +1695,20 @@ impl MallocSizeOf for ExtraStyleData { > n > } > } > > /// SelectorMapEntry implementation for use in our revalidation selector map. > #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] > #[derive(Clone, Debug)] > struct RevalidationSelectorAndHashes { >- #[cfg_attr(feature = "gecko", >- ignore_malloc_size_of = "CssRules have primary refs, we measure there")] >+ #[cfg_attr( >+ feature = "gecko", >+ ignore_malloc_size_of = "CssRules have primary refs, we measure there" >+ )] > selector: Selector<SelectorImpl>, > selector_offset: usize, > hashes: AncestorHashes, > } > > impl RevalidationSelectorAndHashes { > fn new(selector: Selector<SelectorImpl>, hashes: AncestorHashes) -> Self { > let selector_offset = { >@@ -1766,31 +1774,31 @@ fn component_needs_revalidation( > match *c { > Component::ID(_) => { > // TODO(emilio): This could also check that the ID is not already in > // the rule hash. In that case, we could avoid making this a > // revalidation selector too. > // > // See https://bugzilla.mozilla.org/show_bug.cgi?id=1369611 > passed_rightmost_selector >- }, >- Component::AttributeInNoNamespaceExists { .. } | >- Component::AttributeInNoNamespace { .. } | >- Component::AttributeOther(_) | >- Component::Empty | >- Component::FirstChild | >- Component::LastChild | >- Component::OnlyChild | >- Component::NthChild(..) | >- Component::NthLastChild(..) | >- Component::NthOfType(..) | >- Component::NthLastOfType(..) | >- Component::FirstOfType | >- Component::LastOfType | >- Component::OnlyOfType => true, >+ } >+ Component::AttributeInNoNamespaceExists { .. } >+ | Component::AttributeInNoNamespace { .. } >+ | Component::AttributeOther(_) >+ | Component::Empty >+ | Component::FirstChild >+ | Component::LastChild >+ | Component::OnlyChild >+ | Component::NthChild(..) >+ | Component::NthLastChild(..) >+ | Component::NthOfType(..) >+ | Component::NthLastOfType(..) >+ | Component::FirstOfType >+ | Component::LastOfType >+ | Component::OnlyOfType => true, > Component::NonTSPseudoClass(ref p) => p.needs_cache_revalidation(), > _ => false, > } > } > > impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> { > type Impl = SelectorImpl; > >@@ -1800,18 +1808,19 @@ impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> { > > // NOTE(emilio): This works properly right now because we can't store > // complex selectors in nested selectors, otherwise we may need to > // rethink this. > // > // Also, note that this call happens before we visit any of the simple > // selectors in the next ComplexSelector, so we can use this to skip > // looking at them. >- self.passed_rightmost_selector = self.passed_rightmost_selector || >- !matches!(combinator, None | Some(Combinator::PseudoElement)); >+ self.passed_rightmost_selector = >+ self.passed_rightmost_selector >+ || !matches!(combinator, None | Some(Combinator::PseudoElement)); > > true > } > > fn visit_attribute_selector( > &mut self, > _ns: &NamespaceConstraint<&Namespace>, > name: &LocalName, >@@ -1823,40 +1832,41 @@ impl<'a> SelectorVisitor for StylistSelectorVisitor<'a> { > self.attribute_dependencies.insert_hash(name.get_hash()); > self.attribute_dependencies > .insert_hash(lower_name.get_hash()); > } > true > } > > fn visit_simple_selector(&mut self, s: &Component<SelectorImpl>) -> bool { >- self.needs_revalidation = self.needs_revalidation || >- component_needs_revalidation(s, self.passed_rightmost_selector); >+ self.needs_revalidation = >+ self.needs_revalidation >+ || component_needs_revalidation(s, self.passed_rightmost_selector); > > match *s { > Component::NonTSPseudoClass(ref p) => { > self.state_dependencies.insert(p.state_flag()); > self.document_state_dependencies > .insert(p.document_state_flag()); >- }, >+ } > Component::ID(ref id) if !self.passed_rightmost_selector => { > // We want to stop storing mapped ids as soon as we've moved off > // the rightmost ComplexSelector that is not a pseudo-element. > // > // That can be detected by a visit_complex_selector call with a > // combinator other than None and PseudoElement. > // > // Importantly, this call happens before we visit any of the > // simple selectors in that ComplexSelector. > // > // NOTE(emilio): See the comment regarding on when this may > // break in visit_complex_selector. > self.mapped_ids.insert_hash(id.get_hash()); >- }, >- _ => {}, >+ } >+ _ => {} > } > > true > } > } > > /// A set of rules for element and pseudo-elements. > #[derive(Debug, Default, MallocSizeOf)] >@@ -1880,17 +1890,18 @@ impl ElementAndPseudoRules { > rule: Rule, > pseudo_element: Option<&PseudoElement>, > quirks_mode: QuirksMode, > ) -> Result<(), FailedAllocationError> { > debug_assert!(pseudo_element.map_or(true, |pseudo| !pseudo.is_precomputed())); > > let map = match pseudo_element { > None => &mut self.element_map, >- Some(pseudo) => self.pseudos_map >+ Some(pseudo) => self >+ .pseudos_map > .get_or_insert_with(pseudo, || Box::new(SelectorMap::new())), > }; > > map.insert(rule, quirks_mode) > } > > fn clear(&mut self) { > self.element_map.clear(); >@@ -2041,17 +2052,17 @@ impl CascadeData { > { > if !collection.dirty() { > return Ok(()); > } > > let validity = collection.data_validity(); > > match validity { >- DataValidity::Valid => {}, >+ DataValidity::Valid => {} > DataValidity::CascadeInvalid => self.clear_cascade_data(), > DataValidity::FullyInvalid => self.clear(), > } > > for (stylesheet, rebuild_kind) in collection { > self.add_stylesheet( > device, > quirks_mode, >@@ -2127,23 +2138,23 @@ impl CascadeData { > results.saw_effective(stylesheet); > > for rule in stylesheet.effective_rules(device, guard) { > match *rule { > CssRule::Import(ref lock) => { > let import_rule = lock.read_with(guard); > debug!(" + {:?}", import_rule.stylesheet.media(guard)); > results.saw_effective(import_rule); >- }, >+ } > CssRule::Media(ref lock) => { > let media_rule = lock.read_with(guard); > debug!(" + {:?}", media_rule.media_queries.read_with(guard)); > results.saw_effective(media_rule); >- }, >- _ => {}, >+ } >+ _ => {} > } > } > } > > // Returns Err(..) to signify OOM > fn add_stylesheet<S>( > &mut self, > device: &Device, >@@ -2241,71 +2252,71 @@ impl CascadeData { > .get_or_insert_with(|| Box::new(Default::default())) > } else { > &mut self.normal_rules > }; > > rules.insert(rule, pseudo_element, quirks_mode)?; > } > self.rules_source_order += 1; >- }, >+ } > CssRule::Import(ref lock) => { > if rebuild_kind.should_rebuild_invalidation() { > let import_rule = lock.read_with(guard); > self.effective_media_query_results > .saw_effective(import_rule); > } > > // NOTE: effective_rules visits the inner stylesheet if > // appropriate. >- }, >+ } > CssRule::Media(ref lock) => { > if rebuild_kind.should_rebuild_invalidation() { > let media_rule = lock.read_with(guard); > self.effective_media_query_results.saw_effective(media_rule); > } >- }, >+ } > CssRule::Keyframes(ref keyframes_rule) => { > let keyframes_rule = keyframes_rule.read_with(guard); > debug!("Found valid keyframes rule: {:?}", *keyframes_rule); > > // Don't let a prefixed keyframes animation override a non-prefixed one. >- let needs_insertion = keyframes_rule.vendor_prefix.is_none() || >- self.animations >- .get(keyframes_rule.name.as_atom()) >- .map_or(true, |rule| rule.vendor_prefix.is_some()); >+ let needs_insertion = keyframes_rule.vendor_prefix.is_none() || self >+ .animations >+ .get(keyframes_rule.name.as_atom()) >+ .map_or(true, |rule| rule.vendor_prefix.is_some()); > if needs_insertion { > let animation = KeyframesAnimation::from_keyframes( > &keyframes_rule.keyframes, > keyframes_rule.vendor_prefix.clone(), > guard, > ); > debug!("Found valid keyframe animation: {:?}", animation); > self.animations > .try_insert(keyframes_rule.name.as_atom().clone(), animation)?; > } >- }, >+ } > #[cfg(feature = "gecko")] > CssRule::FontFace(ref rule) => { > self.extra_data.add_font_face(rule); >- }, >+ } > #[cfg(feature = "gecko")] > CssRule::FontFeatureValues(ref rule) => { > self.extra_data.add_font_feature_values(rule); >- }, >+ } > #[cfg(feature = "gecko")] > CssRule::CounterStyle(ref rule) => { > self.extra_data.add_counter_style(guard, rule); >- }, >+ } > #[cfg(feature = "gecko")] > CssRule::Page(ref rule) => { > self.extra_data.add_page(rule); >- }, >+ } > // We don't care about any other rule. >- _ => {}, >+ _ => {} > } > } > > Ok(()) > } > > /// Returns whether all the media-feature affected values matched before and > /// match now in the given stylesheet. >@@ -2338,71 +2349,70 @@ impl CascadeData { > if !effective_now { > return true; > } > > let mut iter = stylesheet.iter_rules::<PotentiallyEffectiveMediaRules>(device, guard); > > while let Some(rule) = iter.next() { > match *rule { >- CssRule::Style(..) | >- CssRule::Namespace(..) | >- CssRule::FontFace(..) | >- CssRule::CounterStyle(..) | >- CssRule::Supports(..) | >- CssRule::Keyframes(..) | >- CssRule::Page(..) | >- CssRule::Viewport(..) | >- CssRule::Document(..) | >- CssRule::FontFeatureValues(..) => { >+ CssRule::Style(..) >+ | CssRule::Namespace(..) >+ | CssRule::FontFace(..) >+ | CssRule::CounterStyle(..) >+ | CssRule::Supports(..) >+ | CssRule::Keyframes(..) >+ | CssRule::Page(..) >+ | CssRule::Viewport(..) >+ | CssRule::Document(..) >+ | CssRule::FontFeatureValues(..) => { > // Not affected by device changes. > continue; >- }, >+ } > CssRule::Import(ref lock) => { > let import_rule = lock.read_with(guard); > let effective_now = import_rule > .stylesheet > .is_effective_for_device(&device, guard); >- let effective_then = self.effective_media_query_results >+ let effective_then = self >+ .effective_media_query_results > .was_effective(import_rule); > if effective_now != effective_then { > debug!( > " > @import rule {:?} changed {} -> {}", > import_rule.stylesheet.media(guard), > effective_then, > effective_now > ); > return false; > } > > if !effective_now { > iter.skip_children(); > } >- }, >+ } > CssRule::Media(ref lock) => { > let media_rule = lock.read_with(guard); > let mq = media_rule.media_queries.read_with(guard); > let effective_now = mq.evaluate(device, quirks_mode); > let effective_then = > self.effective_media_query_results.was_effective(media_rule); > > if effective_now != effective_then { > debug!( > " > @media rule {:?} changed {} -> {}", >- mq, >- effective_then, >- effective_now >+ mq, effective_then, effective_now > ); > return false; > } > > if !effective_now { > iter.skip_children(); > } >- }, >+ } > } > } > > true > } > > /// Clears the cascade data, but not the invalidation data. > fn clear_cascade_data(&mut self) { >@@ -2465,18 +2475,20 @@ pub struct Rule { > pub hashes: AncestorHashes, > > /// The source order this style rule appears in. Note that we only use > /// three bytes to store this value in ApplicableDeclarationsBlock, so > /// we could repurpose that storage here if we needed to. > pub source_order: u32, > > /// The actual style rule. >- #[cfg_attr(feature = "gecko", >- ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet.")] >+ #[cfg_attr( >+ feature = "gecko", >+ ignore_malloc_size_of = "Secondary ref. Primary ref is in StyleRule under Stylesheet." >+ )] > #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] > pub style_rule: Arc<Locked<StyleRule>>, > } > > impl SelectorMapEntry for Rule { > fn selector(&self) -> SelectorIter<SelectorImpl> { > self.selector.iter() > } >@@ -2491,17 +2503,23 @@ impl Rule { > /// Turns this rule into an `ApplicableDeclarationBlock` for the given > /// cascade level. > pub fn to_applicable_declaration_block( > &self, > level: CascadeLevel, > shadow_cascade_order: ShadowCascadeOrder, > ) -> ApplicableDeclarationBlock { > let source = StyleSource::from_rule(self.style_rule.clone()); >- ApplicableDeclarationBlock::new(source, self.source_order, level, self.specificity(), shadow_cascade_order) >+ ApplicableDeclarationBlock::new( >+ source, >+ self.source_order, >+ level, >+ self.specificity(), >+ shadow_cascade_order, >+ ) > } > > /// Creates a new Rule. > pub fn new( > selector: Selector<SelectorImpl>, > hashes: AncestorHashes, > style_rule: Arc<Locked<StyleRule>>, > source_order: u32, >diff --git a/servo/components/style/timer.rs b/servo/components/style/timer.rs >index 54e6fcdfd90f..e9d9e71a13a4 100644 >--- a/servo/components/style/timer.rs >+++ b/servo/components/style/timer.rs >@@ -52,12 +52,12 @@ impl Timer { > } > > /// Increments the current clock. Panics if the clock is not on test mode. > pub fn increment(&mut self, by: f64) { > match self.mode { > TimerMode::Test(ref mut val) => *val += by, > TimerMode::Current => { > panic!("Timer::increment called for a non-test mode timer. This is a bug.") >- }, >+ } > } > } > } >diff --git a/servo/components/style/traversal.rs b/servo/components/style/traversal.rs >index 0bffd39819c4..200c31d82405 100644 >--- a/servo/components/style/traversal.rs >+++ b/servo/components/style/traversal.rs >@@ -202,22 +202,22 @@ pub trait DomTraversal<E: TElement>: Sync { > "element_needs_traversal({:?}, {:?}, {:?})", > el, traversal_flags, data > ); > > // In case of animation-only traversal we need to traverse the element > // if the element has animation only dirty descendants bit, > // animation-only restyle hint or recascade. > if traversal_flags.for_animation_only() { >- return data.map_or(false, |d| d.has_styles()) && >- (el.has_animation_only_dirty_descendants() || >- data.as_ref() >- .unwrap() >- .hint >- .has_animation_hint_or_recascade()); >+ return data.map_or(false, |d| d.has_styles()) >+ && (el.has_animation_only_dirty_descendants() || data >+ .as_ref() >+ .unwrap() >+ .hint >+ .has_animation_hint_or_recascade()); > } > > // Non-incremental layout visits every node. > if is_servo_nonincremental_layout() { > return true; > } > > // Unwrap the data. >@@ -274,18 +274,19 @@ pub trait DomTraversal<E: TElement>: Sync { > > // Gecko-only XBL handling. > // > // When we apply the XBL binding during frame construction, we restyle > // the whole subtree again if the binding is valid, so assuming it's > // likely to load valid bindings, we avoid wasted work here, which may > // be a very big perf hit when elements with bindings are nested > // heavily. >- if cfg!(feature = "gecko") && is_initial_style && >- parent_data.styles.primary().has_moz_binding() >+ if cfg!(feature = "gecko") >+ && is_initial_style >+ && parent_data.styles.primary().has_moz_binding() > { > debug!("Parent {:?} has XBL binding, deferring traversal", parent); > return true; > } > > return false; > } > >@@ -304,19 +305,19 @@ pub fn resolve_style<E>( > pseudo: Option<&PseudoElement>, > ) -> ElementStyles > where > E: TElement, > { > use style_resolver::StyleResolverForElement; > > debug_assert!( >- rule_inclusion == RuleInclusion::DefaultOnly || >- pseudo.map_or(false, |p| p.is_before_or_after()) || >- element.borrow_data().map_or(true, |d| !d.has_styles()), >+ rule_inclusion == RuleInclusion::DefaultOnly >+ || pseudo.map_or(false, |p| p.is_before_or_after()) >+ || element.borrow_data().map_or(true, |d| !d.has_styles()), > "Why are we here?" > ); > let mut ancestors_requiring_style_resolution = SmallVec::<[E; 16]>::new(); > > // Clear the bloom filter, just in case the caller is reusing TLS. > context.thread_local.bloom_filter.clear(); > > let mut style = None; >@@ -379,18 +380,17 @@ where > StyleResolverForElement::new( > element, > context, > rule_inclusion, > PseudoElementResolution::Force, > ).resolve_style( > style.as_ref().map(|s| &**s), > layout_parent_style.as_ref().map(|s| &**s), >- ) >- .into() >+ ).into() > } > > /// Calculates the style for a single node. > #[inline] > #[allow(unsafe_code)] > pub fn recalc_style_at<E, D, F>( > traversal: &D, > traversal_data: &PerLevelTraversalData, >@@ -406,18 +406,19 @@ pub fn recalc_style_at<E, D, F>( > use std::cmp; > use traversal_flags::TraversalFlags; > > let flags = context.shared.traversal_flags; > let is_initial_style = !data.has_styles(); > > context.thread_local.statistics.elements_traversed += 1; > debug_assert!( >- flags.intersects(TraversalFlags::AnimationOnly) || !element.has_snapshot() || >- element.handled_snapshot(), >+ flags.intersects(TraversalFlags::AnimationOnly) >+ || !element.has_snapshot() >+ || element.handled_snapshot(), > "Should've handled snapshots here already" > ); > > let compute_self = !element.has_current_styles_for_traversal(data, flags); > > debug!( > "recalc_style_at: {:?} (compute_self={:?}, \ > dirty_descendants={:?}, data={:?})", >@@ -502,23 +503,24 @@ pub fn recalc_style_at<E, D, F>( > // * We have the dirty descendants bit. > // * We're propagating a restyle hint. > // * We can't skip the cascade. > // * This is a servo non-incremental traversal. > // > // Additionally, there are a few scenarios where we avoid traversing the > // subtree even if descendant styles are out of date. These cases are > // enumerated in should_cull_subtree(). >- let mut traverse_children = has_dirty_descendants_for_this_restyle || >- !propagated_hint.is_empty() || >- !child_cascade_requirement.can_skip_cascade() || >- is_servo_nonincremental_layout(); >+ let mut traverse_children = has_dirty_descendants_for_this_restyle >+ || !propagated_hint.is_empty() >+ || !child_cascade_requirement.can_skip_cascade() >+ || is_servo_nonincremental_layout(); > >- traverse_children = traverse_children && >- !traversal.should_cull_subtree(context, element, &data, is_initial_style); >+ traverse_children = >+ traverse_children >+ && !traversal.should_cull_subtree(context, element, &data, is_initial_style); > > // Examine our children, and enqueue the appropriate ones for traversal. > if traverse_children { > note_children::<E, D, F>( > context, > element, > data, > propagated_hint, >@@ -530,18 +532,19 @@ pub fn recalc_style_at<E, D, F>( > > // FIXME(bholley): Make these assertions pass for servo. > if cfg!(feature = "gecko") && cfg!(debug_assertions) && data.styles.is_display_none() { > debug_assert!(!element.has_dirty_descendants()); > debug_assert!(!element.has_animation_only_dirty_descendants()); > } > > debug_assert!( >- flags.for_animation_only() || !flags.contains(TraversalFlags::ClearDirtyBits) || >- !element.has_animation_only_dirty_descendants(), >+ flags.for_animation_only() >+ || !flags.contains(TraversalFlags::ClearDirtyBits) >+ || !element.has_animation_only_dirty_descendants(), > "Should have cleared animation bits already" > ); > clear_state_after_traversing(element, data, flags); > } > > fn clear_state_after_traversing<E>(element: E, data: &mut ElementData, flags: TraversalFlags) > where > E: TElement, >@@ -617,17 +620,17 @@ where > let mut target = StyleSharingTarget::new(element); > > // Now that our bloom filter is set up, try the style sharing > // cache. > match target.share_style_if_possible(context) { > Some(shared_styles) => { > context.thread_local.statistics.styles_shared += 1; > shared_styles >- }, >+ } > None => { > context.thread_local.statistics.elements_matched += 1; > // Perform the matching and cascading. > let new_styles = { > let mut resolver = StyleResolverForElement::new( > element, > context, > RuleInclusion::All, >@@ -640,33 +643,33 @@ where > context.thread_local.sharing_cache.insert_if_possible( > &element, > &new_styles.primary, > Some(&mut target), > traversal_data.current_dom_depth, > ); > > new_styles >- }, >+ } > } >- }, >+ } > CascadeWithReplacements(flags) => { > // Skipping full matching, load cascade inputs from previous values. > let mut cascade_inputs = ElementCascadeInputs::new_from_element_data(data); > important_rules_changed = element.replace_rules(flags, context, &mut cascade_inputs); > > let mut resolver = StyleResolverForElement::new( > element, > context, > RuleInclusion::All, > PseudoElementResolution::IfApplicable, > ); > > resolver.cascade_styles_with_default_parents(cascade_inputs) >- }, >+ } > CascadeOnly => { > // Skipping full matching, load cascade inputs from previous values. > let cascade_inputs = ElementCascadeInputs::new_from_element_data(data); > > let new_styles = { > let mut resolver = StyleResolverForElement::new( > element, > context, >@@ -697,41 +700,41 @@ where > &element, > &new_styles.primary, > None, > traversal_data.current_dom_depth, > ); > } > > new_styles >- }, >+ } > }; > > element.finish_restyle(context, data, new_styles, important_rules_changed) > } > > #[cfg(feature = "servo")] > fn notify_paint_worklet<E>(context: &StyleContext<E>, data: &ElementData) > where > E: TElement, > { > use style_traits::ToCss; >- use values::Either; > use values::generics::image::Image; >+ use values::Either; > > // We speculatively evaluate any paint worklets during styling. > // This allows us to run paint worklets in parallel with style and layout. > // Note that this is wasted effort if the size of the node has > // changed, but in may cases it won't have. > if let Some(ref values) = data.styles.primary { > for image in &values.get_background().background_image.0 { > let (name, arguments) = match *image { > Either::Second(Image::PaintWorklet(ref worklet)) => { > (&worklet.name, &worklet.arguments) >- }, >+ } > _ => continue, > }; > let painter = match context.shared.registered_speculative_painters.get(name) { > Some(painter) => painter, > None => continue, > }; > let properties = painter > .properties() >@@ -773,56 +776,56 @@ fn note_children<E, D, F>( > trace!("note_children: {:?}", element); > let flags = context.shared.traversal_flags; > > // Loop over all the traversal children. > for child_node in element.traversal_children() { > let child = match child_node.as_element() { > Some(el) => el, > None => { >- if is_servo_nonincremental_layout() || >- D::text_node_needs_traversal(child_node, data) >+ if is_servo_nonincremental_layout() >+ || D::text_node_needs_traversal(child_node, data) > { > note_child(child_node); > } > continue; >- }, >+ } > }; > > let mut child_data = child.mutate_data(); > let mut child_data = child_data.as_mut().map(|d| &mut **d); > trace!( > " > {:?} -> {:?} + {:?}, pseudo: {:?}", > child, > child_data.as_ref().map(|d| d.hint), > propagated_hint, > child.implemented_pseudo_element() > ); > > if let Some(ref mut child_data) = child_data { > let mut child_hint = propagated_hint; > match cascade_requirement { >- ChildCascadeRequirement::CanSkipCascade => {}, >+ ChildCascadeRequirement::CanSkipCascade => {} > ChildCascadeRequirement::MustCascadeDescendants => { > child_hint |= RestyleHint::RECASCADE_SELF | RestyleHint::RECASCADE_DESCENDANTS; >- }, >+ } > ChildCascadeRequirement::MustCascadeChildrenIfInheritResetStyle => { > use properties::computed_value_flags::ComputedValueFlags; > if child_data > .styles > .primary() > .flags > .contains(ComputedValueFlags::INHERITS_RESET_STYLE) > { > child_hint |= RestyleHint::RECASCADE_SELF; > } >- }, >+ } > ChildCascadeRequirement::MustCascadeChildren => { > child_hint |= RestyleHint::RECASCADE_SELF; >- }, >+ } > } > > child_data.hint.insert(child_hint); > > // Handle element snapshots and invalidation of descendants and siblings > // as needed. > // > // NB: This will be a no-op if there's no snapshot. >diff --git a/servo/components/style/values/animated/color.rs b/servo/components/style/values/animated/color.rs >index 4356c5a3d9bf..2a6a8827f8d7 100644 >--- a/servo/components/style/values/animated/color.rs >+++ b/servo/components/style/values/animated/color.rs >@@ -55,18 +55,19 @@ impl Animate for RGBA { > // Ideally we should return color value that only alpha component is > // 0, but this is what current gecko does. > return Ok(RGBA::transparent()); > } > > alpha = alpha.min(1.); > let red = > (self.red * self.alpha).animate(&(other.red * other.alpha), procedure)? * 1. / alpha; >- let green = (self.green * self.alpha).animate(&(other.green * other.alpha), procedure)? * >- 1. / alpha; >+ let green = (self.green * self.alpha).animate(&(other.green * other.alpha), procedure)? >+ * 1. >+ / alpha; > let blue = > (self.blue * self.alpha).animate(&(other.blue * other.alpha), procedure)? * 1. / alpha; > > Ok(RGBA::new(red, green, blue, alpha)) > } > } > > impl ComputeSquaredDistance for RGBA { >diff --git a/servo/components/style/values/animated/effects.rs b/servo/components/style/values/animated/effects.rs >index a201ec0549e3..dca36779ebc7 100644 >--- a/servo/components/style/values/animated/effects.rs >+++ b/servo/components/style/values/animated/effects.rs >@@ -1,25 +1,25 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Animated types for CSS values related to effects. > >-#[cfg(not(feature = "gecko"))] >-use values::Impossible; > use values::animated::color::Color; >-use values::computed::{Angle, Number}; > use values::computed::length::Length; > #[cfg(feature = "gecko")] > use values::computed::url::ComputedUrl; >+use values::computed::{Angle, Number}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; > use values::generics::effects::BoxShadow as GenericBoxShadow; > use values::generics::effects::Filter as GenericFilter; > use values::generics::effects::SimpleShadow as GenericSimpleShadow; >+#[cfg(not(feature = "gecko"))] >+use values::Impossible; > > /// An animated value for a single `box-shadow`. > pub type BoxShadow = GenericBoxShadow<Color, Length, Length, Length>; > > /// An animated value for a single `filter`. > #[cfg(feature = "gecko")] > pub type Filter = GenericFilter<Angle, Number, Length, SimpleShadow, ComputedUrl>; > >@@ -31,12 +31,12 @@ pub type Filter = GenericFilter<Angle, Number, Length, Impossible, Impossible>; > pub type SimpleShadow = GenericSimpleShadow<Color, Length, Length>; > > impl ComputeSquaredDistance for BoxShadow { > #[inline] > fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { > if self.inset != other.inset { > return Err(()); > } >- Ok(self.base.compute_squared_distance(&other.base)? + >- self.spread.compute_squared_distance(&other.spread)?) >+ Ok(self.base.compute_squared_distance(&other.base)? >+ + self.spread.compute_squared_distance(&other.spread)?) > } > } >diff --git a/servo/components/style/values/animated/mod.rs b/servo/components/style/values/animated/mod.rs >index 53d3719b0213..0d23e062767d 100644 >--- a/servo/components/style/values/animated/mod.rs >+++ b/servo/components/style/values/animated/mod.rs >@@ -6,22 +6,22 @@ > //! > //! Some values, notably colors, cannot be interpolated directly with their > //! computed values and need yet another intermediate representation. This > //! module's raison d'être is to ultimately contain all these types. > > use app_units::Au; > use euclid::{Point2D, Size2D}; > use smallvec::SmallVec; >+use values::computed::length::CalcLengthOrPercentage; >+use values::computed::url::ComputedUrl; > use values::computed::Angle as ComputedAngle; > use values::computed::BorderCornerRadius as ComputedBorderCornerRadius; > use values::computed::MaxLength as ComputedMaxLength; > use values::computed::MozLength as ComputedMozLength; >-use values::computed::length::CalcLengthOrPercentage; >-use values::computed::url::ComputedUrl; > > pub mod color; > pub mod effects; > > /// Animate from one value to another. > /// > /// This trait is derivable with `#[derive(Animate)]`. The derived > /// implementation uses a `match` expression with identical patterns for both >@@ -292,24 +292,24 @@ impl ToAnimatedValue for ComputedMaxLength { > #[inline] > fn from_animated_value(animated: Self::AnimatedValue) -> Self { > use values::computed::{Length, LengthOrPercentageOrNone, Percentage}; > match animated { > ComputedMaxLength::LengthOrPercentageOrNone(lopn) => { > let result = match lopn { > LengthOrPercentageOrNone::Length(px) => { > LengthOrPercentageOrNone::Length(Length::new(px.px().max(0.))) >- }, >+ } > LengthOrPercentageOrNone::Percentage(percentage) => { > LengthOrPercentageOrNone::Percentage(Percentage(percentage.0.max(0.))) >- }, >+ } > _ => lopn, > }; > ComputedMaxLength::LengthOrPercentageOrNone(result) >- }, >+ } > _ => animated, > } > } > } > > impl ToAnimatedValue for ComputedMozLength { > type AnimatedValue = Self; > >@@ -321,24 +321,24 @@ impl ToAnimatedValue for ComputedMozLength { > #[inline] > fn from_animated_value(animated: Self::AnimatedValue) -> Self { > use values::computed::{Length, LengthOrPercentageOrAuto, Percentage}; > match animated { > ComputedMozLength::LengthOrPercentageOrAuto(lopa) => { > let result = match lopa { > LengthOrPercentageOrAuto::Length(px) => { > LengthOrPercentageOrAuto::Length(Length::new(px.px().max(0.))) >- }, >+ } > LengthOrPercentageOrAuto::Percentage(percentage) => { > LengthOrPercentageOrAuto::Percentage(Percentage(percentage.0.max(0.))) >- }, >+ } > _ => lopa, > }; > ComputedMozLength::LengthOrPercentageOrAuto(result) >- }, >+ } > _ => animated, > } > } > } > > impl ToAnimatedZero for Au { > #[inline] > fn to_animated_zero(&self) -> Result<Self, ()> { >diff --git a/servo/components/style/values/computed/angle.rs b/servo/components/style/values/computed/angle.rs >index 67ea5d1231bd..f304e329f21e 100644 >--- a/servo/components/style/values/computed/angle.rs >+++ b/servo/components/style/values/computed/angle.rs >@@ -1,26 +1,28 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed angles. > > use num_traits::Zero; >-use std::{f32, f64}; > use std::f64::consts::PI; > use std::ops::Add; >-use values::CSSFloat; >+use std::{f32, f64}; > use values::animated::{Animate, Procedure}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; >+use values::CSSFloat; > > /// A computed angle. > #[animate(fallback = "Self::animate_fallback")] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, ToAnimatedZero, ToCss, >+)] > pub enum Angle { > /// An angle with degree unit. > #[css(dimension)] > Deg(CSSFloat), > /// An angle with gradian unit. > #[css(dimension)] > Grad(CSSFloat), > /// An angle with radian unit. >@@ -68,17 +70,19 @@ impl Angle { > pub fn degrees(&self) -> f32 { > use std::f32::consts::PI; > self.radians() * 360. / (2. * PI) > } > > /// <https://drafts.csswg.org/css-transitions/#animtype-number> > #[inline] > fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { >- Ok(Angle::from_radians(self.radians().animate(&other.radians(), procedure)?)) >+ Ok(Angle::from_radians( >+ self.radians().animate(&other.radians(), procedure)?, >+ )) > } > } > > impl AsRef<Angle> for Angle { > #[inline] > fn as_ref(&self) -> &Self { > self > } >diff --git a/servo/components/style/values/computed/background.rs b/servo/components/style/values/computed/background.rs >index e94bece983e5..bd701b735943 100644 >--- a/servo/components/style/values/computed/background.rs >+++ b/servo/components/style/values/computed/background.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for CSS values related to backgrounds. > > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; >-use values::computed::{Context, ToComputedValue}; > use values::computed::length::NonNegativeLengthOrPercentageOrAuto; >+use values::computed::{Context, ToComputedValue}; > use values::generics::background::BackgroundSize as GenericBackgroundSize; > use values::specified::background::BackgroundRepeat as SpecifiedBackgroundRepeat; > use values::specified::background::BackgroundRepeatKeyword; > > /// A computed value for the `background-size` property. > pub type BackgroundSize = GenericBackgroundSize<NonNegativeLengthOrPercentageOrAuto>; > > impl BackgroundSize { >@@ -44,28 +44,28 @@ impl BackgroundRepeat { > impl ToCss for BackgroundRepeat { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > match (self.0, self.1) { > (BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat) => { > dest.write_str("repeat-x") >- }, >+ } > (BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat) => { > dest.write_str("repeat-y") >- }, >+ } > (horizontal, vertical) => { > horizontal.to_css(dest)?; > if horizontal != vertical { > dest.write_str(" ")?; > vertical.to_css(dest)?; > } > Ok(()) >- }, >+ } > } > } > } > > impl ToComputedValue for SpecifiedBackgroundRepeat { > type ComputedValue = BackgroundRepeat; > > #[inline] >@@ -76,29 +76,29 @@ impl ToComputedValue for SpecifiedBackgroundRepeat { > BackgroundRepeatKeyword::NoRepeat, > ), > SpecifiedBackgroundRepeat::RepeatY => BackgroundRepeat( > BackgroundRepeatKeyword::NoRepeat, > BackgroundRepeatKeyword::Repeat, > ), > SpecifiedBackgroundRepeat::Keywords(horizontal, vertical) => { > BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)) >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > // FIXME(emilio): Why can't this just be: > // SpecifiedBackgroundRepeat::Keywords(computed.0, computed.1) > match (computed.0, computed.1) { > (BackgroundRepeatKeyword::Repeat, BackgroundRepeatKeyword::NoRepeat) => { > SpecifiedBackgroundRepeat::RepeatX >- }, >+ } > (BackgroundRepeatKeyword::NoRepeat, BackgroundRepeatKeyword::Repeat) => { > SpecifiedBackgroundRepeat::RepeatY >- }, >+ } > (horizontal, vertical) => { > SpecifiedBackgroundRepeat::Keywords(horizontal, Some(vertical)) >- }, >+ } > } > } > } >diff --git a/servo/components/style/values/computed/basic_shape.rs b/servo/components/style/values/computed/basic_shape.rs >index c140439af4ef..770e37f523fb 100644 >--- a/servo/components/style/values/computed/basic_shape.rs >+++ b/servo/components/style/values/computed/basic_shape.rs >@@ -4,18 +4,18 @@ > > //! CSS handling for the computed value of > //! [`basic-shape`][basic-shape]s > //! > //! [basic-shape]: https://drafts.csswg.org/css-shapes/#typedef-basic-shape > > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; >-use values::computed::{Image, LengthOrPercentage}; > use values::computed::url::ComputedUrl; >+use values::computed::{Image, LengthOrPercentage}; > use values::generics::basic_shape as generic; > > /// A computed clipping shape. > pub type ClippingShape = generic::ClippingShape<BasicShape, ComputedUrl>; > > /// A computed float area shape. > pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>; > >diff --git a/servo/components/style/values/computed/border.rs b/servo/components/style/values/computed/border.rs >index cf97a96ad736..a305d03803f1 100644 >--- a/servo/components/style/values/computed/border.rs >+++ b/servo/components/style/values/computed/border.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for CSS values related to borders. > > use app_units::Au; > use values::animated::ToAnimatedZero; >-use values::computed::{Number, NumberOrPercentage}; > use values::computed::length::{LengthOrPercentage, NonNegativeLength}; >+use values::computed::{Number, NumberOrPercentage}; > use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; > use values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; > use values::generics::border::BorderImageSlice as GenericBorderImageSlice; > use values::generics::border::BorderRadius as GenericBorderRadius; > use values::generics::border::BorderSpacing as GenericBorderSpacing; > use values::generics::rect::Rect; > use values::generics::size::Size; > >diff --git a/servo/components/style/values/computed/box.rs b/servo/components/style/values/computed/box.rs >index 15e447ea4156..a1ca87aeac86 100644 >--- a/servo/components/style/values/computed/box.rs >+++ b/servo/components/style/values/computed/box.rs >@@ -1,24 +1,26 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for box properties. > >-use values::computed::{Context, Number, ToComputedValue}; > use values::computed::length::{LengthOrPercentage, NonNegativeLength}; >+use values::computed::{Context, Number, ToComputedValue}; > use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; > use values::generics::box_::Perspective as GenericPerspective; > use values::generics::box_::VerticalAlign as GenericVerticalAlign; > use values::specified::box_ as specified; > > pub use values::specified::box_::{AnimationName, Appearance, Contain, Display, OverflowClipBox}; > pub use values::specified::box_::{Clear as SpecifiedClear, Float as SpecifiedFloat}; >-pub use values::specified::box_::{OverscrollBehavior, ScrollSnapType, TouchAction, TransitionProperty, WillChange}; >+pub use values::specified::box_::{ >+ OverscrollBehavior, ScrollSnapType, TouchAction, TransitionProperty, WillChange, >+}; > > /// A computed value for the `vertical-align` property. > pub type VerticalAlign = GenericVerticalAlign<LengthOrPercentage>; > > /// A computed value for the `animation-iteration-count` property. > pub type AnimationIterationCount = GenericAnimationIterationCount<Number>; > > impl AnimationIterationCount { >@@ -29,109 +31,119 @@ impl AnimationIterationCount { > } > } > > /// A computed value for the `perspective` property. > pub type Perspective = GenericPerspective<NonNegativeLength>; > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, >+)] > /// A computed value for the `float` property. > pub enum Float { > Left, > Right, >- None >+ None, > } > > impl ToComputedValue for SpecifiedFloat { > type ComputedValue = Float; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > let ltr = context.style().writing_mode.is_bidi_ltr(); > // https://drafts.csswg.org/css-logical-props/#float-clear > match *self { > SpecifiedFloat::InlineStart => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if ltr { > Float::Left > } else { > Float::Right > } >- }, >+ } > SpecifiedFloat::InlineEnd => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if ltr { > Float::Right > } else { > Float::Left > } >- }, >+ } > SpecifiedFloat::Left => Float::Left, > SpecifiedFloat::Right => Float::Right, >- SpecifiedFloat::None => Float::None >+ SpecifiedFloat::None => Float::None, > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedFloat { > match *computed { > Float::Left => SpecifiedFloat::Left, > Float::Right => SpecifiedFloat::Right, >- Float::None => SpecifiedFloat::None >+ Float::None => SpecifiedFloat::None, > } > } > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >-SpecifiedValueInfo, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, >+)] > /// A computed value for the `clear` property. > pub enum Clear { > None, > Left, > Right, >- Both >+ Both, > } > > impl ToComputedValue for SpecifiedClear { > type ComputedValue = Clear; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > let ltr = context.style().writing_mode.is_bidi_ltr(); > // https://drafts.csswg.org/css-logical-props/#float-clear > match *self { > SpecifiedClear::InlineStart => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if ltr { > Clear::Left > } else { > Clear::Right > } >- }, >+ } > SpecifiedClear::InlineEnd => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if ltr { > Clear::Right > } else { > Clear::Left > } >- }, >+ } > SpecifiedClear::None => Clear::None, > SpecifiedClear::Left => Clear::Left, > SpecifiedClear::Right => Clear::Right, >- SpecifiedClear::Both => Clear::Both >+ SpecifiedClear::Both => Clear::Both, > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> SpecifiedClear { > match *computed { > Clear::None => SpecifiedClear::None, > Clear::Left => SpecifiedClear::Left, >@@ -155,26 +167,30 @@ pub enum Resize { > impl ToComputedValue for specified::Resize { > type ComputedValue = Resize; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Resize { > let is_vertical = context.style().writing_mode.is_vertical(); > match self { > specified::Resize::Inline => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if is_vertical { > Resize::Vertical > } else { > Resize::Horizontal > } > } > specified::Resize::Block => { >- context.rule_cache_conditions.borrow_mut() >+ context >+ .rule_cache_conditions >+ .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if is_vertical { > Resize::Horizontal > } else { > Resize::Vertical > } > } > specified::Resize::None => Resize::None, >diff --git a/servo/components/style/values/computed/color.rs b/servo/components/style/values/computed/color.rs >index 5effffe59661..6d0713ac1d4a 100644 >--- a/servo/components/style/values/computed/color.rs >+++ b/servo/components/style/values/computed/color.rs >@@ -2,18 +2,18 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed color values. > > use cssparser::{Color as CSSParserColor, RGBA}; > use std::fmt; > use style_traits::{CssWriter, ToCss}; >-use values::animated::ToAnimatedValue; > use values::animated::color::RGBA as AnimatedRGBA; >+use values::animated::ToAnimatedValue; > use values::generics::color::Color as GenericColor; > > /// Computed value type for the specified RGBAColor. > pub type RGBAColor = RGBA; > > /// The computed value of the `color` property. > pub type ColorPropertyValue = RGBA; > >diff --git a/servo/components/style/values/computed/counters.rs b/servo/components/style/values/computed/counters.rs >index fd8d7763f1cf..211ca6753e7f 100644 >--- a/servo/components/style/values/computed/counters.rs >+++ b/servo/components/style/values/computed/counters.rs >@@ -15,9 +15,8 @@ pub type CounterIncrement = GenericCounterIncrement<i32>; > /// A computed value for the `counter-increment` property. > pub type CounterReset = GenericCounterReset<i32>; > > /// A computed value for the `content` property. > pub type Content = generics::Content<ComputedImageUrl>; > > /// A computed content item. > pub type ContentItem = generics::ContentItem<ComputedImageUrl>; >- >diff --git a/servo/components/style/values/computed/effects.rs b/servo/components/style/values/computed/effects.rs >index 07ac6441b6c5..9a511c4fd89a 100644 >--- a/servo/components/style/values/computed/effects.rs >+++ b/servo/components/style/values/computed/effects.rs >@@ -1,30 +1,32 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for CSS values related to effects. > >-#[cfg(not(feature = "gecko"))] >-use values::Impossible; >-use values::computed::{Angle, NonNegativeNumber}; > use values::computed::color::Color; > use values::computed::length::{Length, NonNegativeLength}; > #[cfg(feature = "gecko")] > use values::computed::url::ComputedUrl; >+use values::computed::{Angle, NonNegativeNumber}; > use values::generics::effects::BoxShadow as GenericBoxShadow; > use values::generics::effects::Filter as GenericFilter; > use values::generics::effects::SimpleShadow as GenericSimpleShadow; >+#[cfg(not(feature = "gecko"))] >+use values::Impossible; > > /// A computed value for a single shadow of the `box-shadow` property. > pub type BoxShadow = GenericBoxShadow<Color, Length, NonNegativeLength, Length>; > > /// A computed value for a single `filter`. > #[cfg(feature = "gecko")] >-pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow, ComputedUrl>; >+pub type Filter = >+ GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, SimpleShadow, ComputedUrl>; > > /// A computed value for a single `filter`. > #[cfg(not(feature = "gecko"))] >-pub type Filter = GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible, Impossible>; >+pub type Filter = >+ GenericFilter<Angle, NonNegativeNumber, NonNegativeLength, Impossible, Impossible>; > > /// A computed value for the `drop-shadow()` filter. > pub type SimpleShadow = GenericSimpleShadow<Color, Length, NonNegativeLength>; >diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs >index 8db4bd7e9171..7ac31c52c183 100644 >--- a/servo/components/style/values/computed/font.rs >+++ b/servo/components/style/values/computed/font.rs >@@ -1,47 +1,46 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed values for font properties > >-use Atom; > use app_units::Au; > use byteorder::{BigEndian, ByteOrder}; > use cssparser::{serialize_identifier, CssStringWriter, Parser}; > #[cfg(feature = "gecko")] >-use gecko_bindings::{bindings, structs}; >-#[cfg(feature = "gecko")] > use gecko_bindings::sugar::refptr::RefPtr; > #[cfg(feature = "gecko")] >+use gecko_bindings::{bindings, structs}; >+#[cfg(feature = "gecko")] > use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; > use std::fmt::{self, Write}; > use std::hash::{Hash, Hasher}; > #[cfg(feature = "servo")] > use std::slice; > use style_traits::{CssWriter, ParseError, ToCss}; >-use values::CSSFloat; > use values::animated::{ToAnimatedValue, ToAnimatedZero}; > use values::computed::{Angle, Context, Integer, NonNegativeLength, NonNegativePercentage}; > use values::computed::{Number, Percentage, ToComputedValue}; > use values::generics::font::{self as generics, FeatureTagValue, FontSettings, VariationValue}; >-use values::specified::font::{self as specified, MIN_FONT_WEIGHT, MAX_FONT_WEIGHT}; >+use values::specified::font::{self as specified, MAX_FONT_WEIGHT, MIN_FONT_WEIGHT}; > use values::specified::length::{FontBaseSize, NoCalcLength}; >+use values::CSSFloat; >+use Atom; > > pub use values::computed::Length as MozScriptMinSize; > pub use values::specified::font::{FontSynthesis, MozScriptSizeMultiplier, XLang, XTextZoom}; > > /// A value for the font-weight property per: > /// > /// https://drafts.csswg.org/css-fonts-4/#propdef-font-weight > /// > /// This is effectively just a `Number`. >-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- ToCss)] >+#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > pub struct FontWeight(pub Number); > > impl Hash for FontWeight { > fn hash<H: Hasher>(&self, hasher: &mut H) { > hasher.write_u64((self.0 * 10000.).trunc() as u64); > } > } >@@ -55,18 +54,27 @@ impl ToAnimatedValue for FontWeight { > } > > #[inline] > fn from_animated_value(animated: Self::AnimatedValue) -> Self { > FontWeight(animated.max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT)) > } > } > >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ ToAnimatedZero, >+ ToCss, >+)] > /// The computed value of font-size > pub struct FontSize { > /// The size. > pub size: NonNegativeLength, > /// If derived from a keyword, the keyword and additional transformations applied to it > #[css(skip)] > pub keyword_info: Option<KeywordInfo>, > } >@@ -212,19 +220,19 @@ impl ToAnimatedValue for FontSize { > #[cfg_attr(feature = "servo", derive(MallocSizeOf))] > /// Specifies a prioritized list of font family names or generic family names. > pub struct FontFamily(pub FontFamilyList); > > impl FontFamily { > #[inline] > /// Get default font family as `serif` which is a generic font-family > pub fn serif() -> Self { >- FontFamily(FontFamilyList::new(Box::new([ >- SingleFontFamily::Generic(atom!("serif")), >- ]))) >+ FontFamily(FontFamilyList::new(Box::new([SingleFontFamily::Generic( >+ atom!("serif"), >+ )]))) > } > } > > #[cfg(feature = "gecko")] > impl MallocSizeOf for FontFamily { > fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { > // SharedFontList objects are generally shared from the pointer > // stored in the specified value. So only count this if the >@@ -263,17 +271,17 @@ impl ToCss for FamilyName { > where > W: fmt::Write, > { > match self.syntax { > FamilyNameSyntax::Quoted => { > dest.write_char('"')?; > write!(CssStringWriter::new(dest), "{}", self.name)?; > dest.write_char('"') >- }, >+ } > FamilyNameSyntax::Identifiers => { > let mut first = true; > for ident in self.name.to_string().split(' ') { > if first { > first = false; > } else { > dest.write_char(' ')?; > } >@@ -281,17 +289,17 @@ impl ToCss for FamilyName { > !ident.is_empty(), > "Family name with leading, \ > trailing, or consecutive white spaces should \ > have been marked quoted by the parser" > ); > serialize_identifier(ident, dest)?; > } > Ok(()) >- }, >+ } > } > } > } > > #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > /// Font family names must either be given quoted as strings, > /// or unquoted as a sequence of one or more identifiers. >@@ -331,22 +339,22 @@ impl SingleFontFamily { > pub fn name(&self) -> &str { > self.atom() > } > > #[cfg(not(feature = "gecko"))] // Gecko can't borrow atoms as UTF-8. > /// Get the corresponding font-family with Atom > pub fn from_atom(input: Atom) -> SingleFontFamily { > match input { >- atom!("serif") | >- atom!("sans-serif") | >- atom!("cursive") | >- atom!("fantasy") | >- atom!("monospace") => return SingleFontFamily::Generic(input), >- _ => {}, >+ atom!("serif") >+ | atom!("sans-serif") >+ | atom!("cursive") >+ | atom!("fantasy") >+ | atom!("monospace") => return SingleFontFamily::Generic(input), >+ _ => {} > } > match_ignore_ascii_case! { &input, > "serif" => return SingleFontFamily::Generic(atom!("serif")), > "sans-serif" => return SingleFontFamily::Generic(atom!("sans-serif")), > "cursive" => return SingleFontFamily::Generic(atom!("cursive")), > "fantasy" => return SingleFontFamily::Generic(atom!("fantasy")), > "monospace" => return SingleFontFamily::Generic(atom!("monospace")), > _ => {} >@@ -468,26 +476,24 @@ impl SingleFontFamily { > use gecko_bindings::structs::FontFamilyType; > > match family.mType { > FontFamilyType::eFamily_sans_serif => SingleFontFamily::Generic(atom!("sans-serif")), > FontFamilyType::eFamily_serif => SingleFontFamily::Generic(atom!("serif")), > FontFamilyType::eFamily_monospace => SingleFontFamily::Generic(atom!("monospace")), > FontFamilyType::eFamily_cursive => SingleFontFamily::Generic(atom!("cursive")), > FontFamilyType::eFamily_fantasy => SingleFontFamily::Generic(atom!("fantasy")), >- FontFamilyType::eFamily_moz_fixed => { >- SingleFontFamily::Generic(atom!("-moz-fixed")) >- }, >+ FontFamilyType::eFamily_moz_fixed => SingleFontFamily::Generic(atom!("-moz-fixed")), > FontFamilyType::eFamily_named => { > let name = Atom::from(&*family.mName); > SingleFontFamily::FamilyName(FamilyName { > name, > syntax: FamilyNameSyntax::Identifiers, > }) >- }, >+ } > FontFamilyType::eFamily_named_quoted => SingleFontFamily::FamilyName(FamilyName { > name: (&*family.mName).into(), > syntax: FamilyNameSyntax::Quoted, > }), > _ => panic!("Found unexpected font FontFamilyType"), > } > } > } >@@ -506,17 +512,17 @@ impl ToCss for SingleFontFamily { > { > // We should treat -moz-fixed as monospace > if name == &atom!("-moz-fixed") { > return dest.write_str("monospace"); > } > } > > write!(dest, "{}", name) >- }, >+ } > } > } > } > > #[cfg(feature = "servo")] > #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)] > /// A list of SingleFontFamily > pub struct FontFamilyList(Box<[SingleFontFamily]>); >@@ -581,23 +587,23 @@ impl FontFamilyList { > let quoted = matches!(f.syntax, FamilyNameSyntax::Quoted); > unsafe { > bindings::Gecko_nsTArray_FontFamilyName_AppendNamed( > names, > f.name.as_ptr(), > quoted, > ); > } >- }, >+ } > SingleFontFamily::Generic(ref name) => { > let (family_type, _generic) = SingleFontFamily::generic(name); > unsafe { > bindings::Gecko_nsTArray_FontFamilyName_AppendGeneric(names, family_type); > } >- }, >+ } > } > } > > FontFamilyList(unsafe { RefPtr::from_addrefed(fontlist) }) > } > > #[cfg(feature = "servo")] > /// Return iterator of SingleFontFamily >@@ -784,17 +790,17 @@ impl ToComputedValue for specified::MozScriptMinSize { > fn to_computed_value(&self, cx: &Context) -> MozScriptMinSize { > // this value is used in the computation of font-size, so > // we use the parent size > let base_size = FontBaseSize::InheritedStyle; > match self.0 { > NoCalcLength::FontRelative(value) => value.to_computed_value(cx, base_size), > NoCalcLength::ServoCharacterWidth(value) => { > value.to_computed_value(base_size.resolve(cx)) >- }, >+ } > ref l => l.to_computed_value(cx), > } > } > > fn from_computed_value(other: &MozScriptMinSize) -> Self { > specified::MozScriptMinSize(ToComputedValue::from_computed_value(other)) > } > } >@@ -814,21 +820,21 @@ impl ToComputedValue for specified::MozScriptLevel { > specified::MozScriptLevel::Auto => { > let parent = cx.builder.get_parent_font().clone__moz_script_level() as i32; > let display = cx.builder.get_parent_font().clone__moz_math_display(); > if display == DisplayValue::Inline { > parent + 1 > } else { > parent > } >- }, >+ } > specified::MozScriptLevel::Relative(rel) => { > let parent = cx.builder.get_parent_font().clone__moz_script_level(); > parent as i32 + rel >- }, >+ } > specified::MozScriptLevel::MozAbsolute(abs) => abs, > }; > cmp::min(int, i8::MAX as i32) as i8 > } > > fn from_computed_value(other: &i8) -> Self { > specified::MozScriptLevel::MozAbsolute(*other as i32) > } >@@ -846,19 +852,20 @@ impl ToAnimatedValue for FontStyleAngle { > #[inline] > fn to_animated_value(self) -> Self::AnimatedValue { > self.0 > } > > #[inline] > fn from_animated_value(animated: Self::AnimatedValue) -> Self { > FontStyleAngle(Angle::Deg( >- animated.degrees() >+ animated >+ .degrees() > .min(specified::FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES) >- .max(specified::FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES) >+ .max(specified::FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES), > )) > } > } > > impl Hash for FontStyleAngle { > fn hash<H: Hasher>(&self, hasher: &mut H) { > hasher.write_u64((self.0.degrees() * 10000.).trunc() as u64); > } >@@ -877,20 +884,21 @@ impl FontStyle { > generics::FontStyle::Normal > } > > /// The default angle for font-style: oblique. This is 20deg per spec: > /// > /// https://drafts.csswg.org/css-fonts-4/#valdef-font-style-oblique-angle > #[inline] > pub fn default_angle() -> FontStyleAngle { >- FontStyleAngle(Angle::Deg(specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES)) >+ FontStyleAngle(Angle::Deg( >+ specified::DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES, >+ )) > } > >- > /// Get the font style from Gecko's nsFont struct. > #[cfg(feature = "gecko")] > pub fn from_gecko(style: structs::FontSlantStyle) -> Self { > let mut angle = 0.; > let mut italic = false; > let mut normal = false; > unsafe { > bindings::Gecko_FontSlantStyle_Get(style, &mut normal, &mut italic, &mut angle); >diff --git a/servo/components/style/values/computed/image.rs b/servo/components/style/values/computed/image.rs >index 91e55c399101..0f80b1f32f97 100644 >--- a/servo/components/style/values/computed/image.rs >+++ b/servo/components/style/values/computed/image.rs >@@ -5,26 +5,26 @@ > //! CSS handling for the computed value of > //! [`image`][image]s > //! > //! [image]: https://drafts.csswg.org/css-images/#image-values > > use std::f32::consts::PI; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; >-use values::{Either, None_}; >-use values::computed::{Angle, Color, Context}; >-use values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; >-#[cfg(feature = "gecko")] >-use values::computed::Percentage; > use values::computed::position::Position; > use values::computed::url::ComputedImageUrl; >+#[cfg(feature = "gecko")] >+use values::computed::Percentage; >+use values::computed::{Angle, Color, Context}; >+use values::computed::{Length, LengthOrPercentage, NumberOrPercentage, ToComputedValue}; > use values::generics::image::{self as generic, CompatMode}; > use values::specified::image::LineDirection as SpecifiedLineDirection; > use values::specified::position::{X, Y}; >+use values::{Either, None_}; > > /// A computed image layer. > pub type ImageLayer = Either<None_, Image>; > > /// Computed values for an image according to CSS-IMAGES. > /// <https://drafts.csswg.org/css-images/#image-values> > pub type Image = generic::Image<Gradient, MozImageRect, ComputedImageUrl>; > >@@ -77,97 +77,97 @@ impl generic::LineDirection for LineDirection { > Some(Position { > horizontal: LengthOrPercentage::Percentage(Percentage(x)), > vertical: LengthOrPercentage::Percentage(Percentage(y)), > }), > None, > ) => { > // `50% 0%` is the default value for line direction. > x == 0.5 && y == 0.0 >- }, >+ } > _ => false, > } > } > > fn to_css<W>(&self, dest: &mut CssWriter<W>, compat_mode: CompatMode) -> fmt::Result > where > W: Write, > { > match *self { > LineDirection::Angle(ref angle) => angle.to_css(dest), > LineDirection::Horizontal(x) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > x.to_css(dest) >- }, >+ } > LineDirection::Vertical(y) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > y.to_css(dest) >- }, >+ } > LineDirection::Corner(x, y) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > x.to_css(dest)?; > dest.write_str(" ")?; > y.to_css(dest) >- }, >+ } > #[cfg(feature = "gecko")] > LineDirection::MozPosition(position, angle) => { > let mut need_space = false; > if let Some(position) = position { > position.to_css(dest)?; > need_space = true; > } > if let Some(angle) = angle { > if need_space { > dest.write_str(" ")?; > } > angle.to_css(dest)?; > } > Ok(()) >- }, >+ } > } > } > } > > impl ToComputedValue for SpecifiedLineDirection { > type ComputedValue = LineDirection; > > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > SpecifiedLineDirection::Angle(ref angle) => { > LineDirection::Angle(angle.to_computed_value(context)) >- }, >+ } > SpecifiedLineDirection::Horizontal(x) => LineDirection::Horizontal(x), > SpecifiedLineDirection::Vertical(y) => LineDirection::Vertical(y), > SpecifiedLineDirection::Corner(x, y) => LineDirection::Corner(x, y), > #[cfg(feature = "gecko")] > SpecifiedLineDirection::MozPosition(ref position, ref angle) => { > LineDirection::MozPosition( > position.to_computed_value(context), > angle.to_computed_value(context), > ) >- }, >+ } > } > } > > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > match *computed { > LineDirection::Angle(ref angle) => { > SpecifiedLineDirection::Angle(ToComputedValue::from_computed_value(angle)) >- }, >+ } > LineDirection::Horizontal(x) => SpecifiedLineDirection::Horizontal(x), > LineDirection::Vertical(y) => SpecifiedLineDirection::Vertical(y), > LineDirection::Corner(x, y) => SpecifiedLineDirection::Corner(x, y), > #[cfg(feature = "gecko")] > LineDirection::MozPosition(ref position, ref angle) => { > SpecifiedLineDirection::MozPosition( > ToComputedValue::from_computed_value(position), > ToComputedValue::from_computed_value(angle), > ) >- }, >+ } > } > } > } >diff --git a/servo/components/style/values/computed/length.rs b/servo/components/style/values/computed/length.rs >index 0ff99a08a3fb..e4ffa084b7ad 100644 >--- a/servo/components/style/values/computed/length.rs >+++ b/servo/components/style/values/computed/length.rs >@@ -1,50 +1,50 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! `<length>` computed values, and related ones. > >+use super::{Context, Number, Percentage, ToComputedValue}; > use app_units::Au; > use logical_geometry::WritingMode; > use ordered_float::NotNan; > use properties::LonghandId; > use std::fmt::{self, Write}; > use std::ops::{Add, Neg}; >-use style_traits::{CssWriter, ToCss}; > use style_traits::values::specified::AllowedNumericType; >-use super::{Context, Number, Percentage, ToComputedValue}; >-use values::{specified, Auto, CSSFloat, Either, Normal}; >+use style_traits::{CssWriter, ToCss}; > use values::animated::{Animate, Procedure, ToAnimatedValue, ToAnimatedZero}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; > use values::generics::NonNegative; >-use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; > use values::specified::length::ViewportPercentageLength; >+use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength}; >+use values::{specified, Auto, CSSFloat, Either, Normal}; > > pub use super::image::Image; > pub use values::specified::url::UrlOrNone; > pub use values::specified::{Angle, BorderStyle, Time}; > > impl ToComputedValue for specified::NoCalcLength { > type ComputedValue = CSSPixelLength; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > specified::NoCalcLength::Absolute(length) => length.to_computed_value(context), > specified::NoCalcLength::FontRelative(length) => { > length.to_computed_value(context, FontBaseSize::CurrentStyle) >- }, >+ } > specified::NoCalcLength::ViewportPercentage(length) => { > length.to_computed_value(context.viewport_size_for_viewport_unit_resolution()) >- }, >+ } > specified::NoCalcLength::ServoCharacterWidth(length) => { > length.to_computed_value(context.style().get_font().clone_font_size().size()) >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > specified::NoCalcLength::Absolute(AbsoluteLength::Px(computed.px())) > } > } >@@ -75,19 +75,21 @@ pub struct CalcLengthOrPercentage { > pub percentage: Option<Percentage>, > } > > impl ComputeSquaredDistance for CalcLengthOrPercentage { > #[inline] > fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { > // FIXME(nox): This looks incorrect to me, to add a distance between lengths > // with a distance between percentages. >- Ok(self.unclamped_length() >- .compute_squared_distance(&other.unclamped_length())? + >- self.percentage() >+ Ok(self >+ .unclamped_length() >+ .compute_squared_distance(&other.unclamped_length())? >+ + self >+ .percentage() > .compute_squared_distance(&other.percentage())?) > } > } > > impl CalcLengthOrPercentage { > /// Returns a new `CalcLengthOrPercentage`. > #[inline] > pub fn new(length: Length, percentage: Option<Percentage>) -> Self { >@@ -144,54 +146,54 @@ impl CalcLengthOrPercentage { > /// If there are special rules for computing percentages in a value (e.g. > /// the height property), they apply whenever a calc() expression contains > /// percentages. > pub fn to_pixel_length(&self, container_len: Option<Au>) -> Option<Length> { > match (container_len, self.percentage) { > (Some(len), Some(percent)) => { > let pixel = self.length.px() + len.scale_by(percent.0).to_f32_px(); > Some(Length::new(self.clamping_mode.clamp(pixel))) >- }, >+ } > (_, None) => Some(self.length()), > _ => None, > } > } > } > > impl From<LengthOrPercentage> for CalcLengthOrPercentage { > fn from(len: LengthOrPercentage) -> CalcLengthOrPercentage { > match len { > LengthOrPercentage::Percentage(this) => { > CalcLengthOrPercentage::new(Length::new(0.), Some(this)) >- }, >+ } > LengthOrPercentage::Length(this) => CalcLengthOrPercentage::new(this, None), > LengthOrPercentage::Calc(this) => this, > } > } > } > > impl From<LengthOrPercentageOrAuto> for Option<CalcLengthOrPercentage> { > fn from(len: LengthOrPercentageOrAuto) -> Option<CalcLengthOrPercentage> { > match len { > LengthOrPercentageOrAuto::Percentage(this) => { > Some(CalcLengthOrPercentage::new(Length::new(0.), Some(this))) >- }, >+ } > LengthOrPercentageOrAuto::Length(this) => Some(CalcLengthOrPercentage::new(this, None)), > LengthOrPercentageOrAuto::Calc(this) => Some(this), > LengthOrPercentageOrAuto::Auto => None, > } > } > } > > impl From<LengthOrPercentageOrNone> for Option<CalcLengthOrPercentage> { > fn from(len: LengthOrPercentageOrNone) -> Option<CalcLengthOrPercentage> { > match len { > LengthOrPercentageOrNone::Percentage(this) => { > Some(CalcLengthOrPercentage::new(Length::new(0.), Some(this))) >- }, >+ } > LengthOrPercentageOrNone::Length(this) => Some(CalcLengthOrPercentage::new(this, None)), > LengthOrPercentageOrNone::Calc(this) => Some(this), > LengthOrPercentageOrNone::None => None, > } > } > } > > impl ToCss for CalcLengthOrPercentage { >@@ -280,29 +282,35 @@ impl specified::CalcLengthOrPercentage { > |abs| context.maybe_zoom_text(abs.into()).0, > base_size, > ) > } > > /// Compute the value into pixel length as CSSFloat without context, > /// so it returns Err(()) if there is any non-absolute unit. > pub fn to_computed_pixel_length_without_context(&self) -> Result<CSSFloat, ()> { >- if self.vw.is_some() || self.vh.is_some() || self.vmin.is_some() || self.vmax.is_some() || >- self.em.is_some() || self.ex.is_some() || self.ch.is_some() || >- self.rem.is_some() || self.percentage.is_some() >+ if self.vw.is_some() >+ || self.vh.is_some() >+ || self.vmin.is_some() >+ || self.vmax.is_some() >+ || self.em.is_some() >+ || self.ex.is_some() >+ || self.ch.is_some() >+ || self.rem.is_some() >+ || self.percentage.is_some() > { > return Err(()); > } > > match self.absolute { > Some(abs) => Ok(abs.to_px()), > None => { > debug_assert!(false, "Someone forgot to handle an unit here: {:?}", self); > Err(()) >- }, >+ } > } > } > } > > impl ToComputedValue for specified::CalcLengthOrPercentage { > type ComputedValue = CalcLengthOrPercentage; > > fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage { >@@ -319,18 +327,27 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { > ..Default::default() > } > } > } > > #[allow(missing_docs)] > #[animate(fallback = "Self::animate_fallback")] > #[css(derive_debug)] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, >- ToAnimatedValue, ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ MallocSizeOf, >+ PartialEq, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToCss, >+)] > #[distance(fallback = "Self::compute_squared_distance_fallback")] > pub enum LengthOrPercentage { > Length(Length), > Percentage(Percentage), > Calc(CalcLengthOrPercentage), > } > > impl LengthOrPercentage { >@@ -410,60 +427,60 @@ impl LengthOrPercentage { > > /// Returns the used value as CSSPixelLength. > pub fn to_pixel_length(&self, containing_length: Au) -> Length { > match *self { > LengthOrPercentage::Length(length) => length, > LengthOrPercentage::Percentage(p) => containing_length.scale_by(p.0).into(), > LengthOrPercentage::Calc(ref calc) => { > calc.to_pixel_length(Some(containing_length)).unwrap() >- }, >+ } > } > } > > /// Returns the clamped non-negative values. > #[inline] > pub fn clamp_to_non_negative(self) -> Self { > match self { > LengthOrPercentage::Length(length) => { > LengthOrPercentage::Length(length.clamp_to_non_negative()) >- }, >+ } > LengthOrPercentage::Percentage(percentage) => { > LengthOrPercentage::Percentage(percentage.clamp_to_non_negative()) >- }, >+ } > _ => self, > } > } > } > > impl ToComputedValue for specified::LengthOrPercentage { > type ComputedValue = LengthOrPercentage; > > fn to_computed_value(&self, context: &Context) -> LengthOrPercentage { > match *self { > specified::LengthOrPercentage::Length(ref value) => { > LengthOrPercentage::Length(value.to_computed_value(context)) >- }, >+ } > specified::LengthOrPercentage::Percentage(value) => { > LengthOrPercentage::Percentage(value) >- }, >+ } > specified::LengthOrPercentage::Calc(ref calc) => { > LengthOrPercentage::Calc((**calc).to_computed_value(context)) >- }, >+ } > } > } > > fn from_computed_value(computed: &LengthOrPercentage) -> Self { > match *computed { > LengthOrPercentage::Length(value) => { > specified::LengthOrPercentage::Length(ToComputedValue::from_computed_value(&value)) >- }, >+ } > LengthOrPercentage::Percentage(value) => { > specified::LengthOrPercentage::Percentage(value) >- }, >+ } > LengthOrPercentage::Calc(ref calc) => specified::LengthOrPercentage::Calc(Box::new( > ToComputedValue::from_computed_value(calc), > )), > } > } > } > > #[allow(missing_docs)] >@@ -478,21 +495,19 @@ pub enum LengthOrPercentageOrAuto { > Calc(CalcLengthOrPercentage), > } > > impl LengthOrPercentageOrAuto { > /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc> > fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { > let this = <Option<CalcLengthOrPercentage>>::from(*self); > let other = <Option<CalcLengthOrPercentage>>::from(*other); >- Ok(LengthOrPercentageOrAuto::Calc(this.animate( >- &other, >- procedure, >- )? >- .ok_or(())?)) >+ Ok(LengthOrPercentageOrAuto::Calc( >+ this.animate(&other, procedure)?.ok_or(())?, >+ )) > } > > #[inline] > fn compute_squared_distance_fallback(&self, other: &Self) -> Result<SquaredDistance, ()> { > <Option<CalcLengthOrPercentage>>::compute_squared_distance( > &(*self).into(), > &(*other).into(), > ) >@@ -551,37 +566,37 @@ impl LengthOrPercentageOrAuto { > impl ToComputedValue for specified::LengthOrPercentageOrAuto { > type ComputedValue = LengthOrPercentageOrAuto; > > #[inline] > fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrAuto { > match *self { > specified::LengthOrPercentageOrAuto::Length(ref value) => { > LengthOrPercentageOrAuto::Length(value.to_computed_value(context)) >- }, >+ } > specified::LengthOrPercentageOrAuto::Percentage(value) => { > LengthOrPercentageOrAuto::Percentage(value) >- }, >+ } > specified::LengthOrPercentageOrAuto::Auto => LengthOrPercentageOrAuto::Auto, > specified::LengthOrPercentageOrAuto::Calc(ref calc) => { > LengthOrPercentageOrAuto::Calc((**calc).to_computed_value(context)) >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &LengthOrPercentageOrAuto) -> Self { > match *computed { > LengthOrPercentageOrAuto::Auto => specified::LengthOrPercentageOrAuto::Auto, > LengthOrPercentageOrAuto::Length(value) => specified::LengthOrPercentageOrAuto::Length( > ToComputedValue::from_computed_value(&value), > ), > LengthOrPercentageOrAuto::Percentage(value) => { > specified::LengthOrPercentageOrAuto::Percentage(value) >- }, >+ } > LengthOrPercentageOrAuto::Calc(calc) => specified::LengthOrPercentageOrAuto::Calc( > Box::new(ToComputedValue::from_computed_value(&calc)), > ), > } > } > } > > #[allow(missing_docs)] >@@ -597,21 +612,19 @@ pub enum LengthOrPercentageOrNone { > None, > } > > impl LengthOrPercentageOrNone { > /// <https://drafts.csswg.org/css-transitions/#animtype-lpcalc> > fn animate_fallback(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { > let this = <Option<CalcLengthOrPercentage>>::from(*self); > let other = <Option<CalcLengthOrPercentage>>::from(*other); >- Ok(LengthOrPercentageOrNone::Calc(this.animate( >- &other, >- procedure, >- )? >- .ok_or(())?)) >+ Ok(LengthOrPercentageOrNone::Calc( >+ this.animate(&other, procedure)?.ok_or(())?, >+ )) > } > > fn compute_squared_distance_fallback(&self, other: &Self) -> Result<SquaredDistance, ()> { > <Option<CalcLengthOrPercentage>>::compute_squared_distance( > &(*self).into(), > &(*other).into(), > ) > } >@@ -620,51 +633,51 @@ impl LengthOrPercentageOrNone { > impl LengthOrPercentageOrNone { > /// Returns the used value. > pub fn to_used_value(&self, containing_length: Au) -> Option<Au> { > match *self { > LengthOrPercentageOrNone::None => None, > LengthOrPercentageOrNone::Length(length) => Some(Au::from(length)), > LengthOrPercentageOrNone::Percentage(percent) => { > Some(containing_length.scale_by(percent.0)) >- }, >+ } > LengthOrPercentageOrNone::Calc(ref calc) => calc.to_used_value(Some(containing_length)), > } > } > } > > impl ToComputedValue for specified::LengthOrPercentageOrNone { > type ComputedValue = LengthOrPercentageOrNone; > > #[inline] > fn to_computed_value(&self, context: &Context) -> LengthOrPercentageOrNone { > match *self { > specified::LengthOrPercentageOrNone::Length(ref value) => { > LengthOrPercentageOrNone::Length(value.to_computed_value(context)) >- }, >+ } > specified::LengthOrPercentageOrNone::Percentage(value) => { > LengthOrPercentageOrNone::Percentage(value) >- }, >+ } > specified::LengthOrPercentageOrNone::Calc(ref calc) => { > LengthOrPercentageOrNone::Calc((**calc).to_computed_value(context)) >- }, >+ } > specified::LengthOrPercentageOrNone::None => LengthOrPercentageOrNone::None, > } > } > > #[inline] > fn from_computed_value(computed: &LengthOrPercentageOrNone) -> Self { > match *computed { > LengthOrPercentageOrNone::None => specified::LengthOrPercentageOrNone::None, > LengthOrPercentageOrNone::Length(value) => specified::LengthOrPercentageOrNone::Length( > ToComputedValue::from_computed_value(&value), > ), > LengthOrPercentageOrNone::Percentage(value) => { > specified::LengthOrPercentageOrNone::Percentage(value) >- }, >+ } > LengthOrPercentageOrNone::Calc(calc) => specified::LengthOrPercentageOrNone::Calc( > Box::new(ToComputedValue::from_computed_value(&calc)), > ), > } > } > } > > /// A wrapper of LengthOrPercentage, whose value must be >= 0. >@@ -722,18 +735,28 @@ impl NonNegativeLengthOrPercentage { > #[inline] > pub fn to_used_value(&self, containing_length: Au) -> Au { > self.0.to_used_value(containing_length) > } > } > > /// The computed `<length>` value. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- PartialOrd, ToAnimatedValue, ToAnimatedZero)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ PartialOrd, >+ ToAnimatedValue, >+ ToAnimatedZero, >+)] > pub struct CSSPixelLength(CSSFloat); > > impl CSSPixelLength { > /// Return a new CSSPixelLength. > #[inline] > pub fn new(px: CSSFloat) -> Self { > CSSPixelLength(px) > } >@@ -911,18 +934,17 @@ pub type NonNegativeLengthOrNormal = Either<NonNegativeLength, Normal>; > > /// Either a computed NonNegativeLengthOrPercentage or the `normal` keyword. > pub type NonNegativeLengthOrPercentageOrNormal = Either<NonNegativeLengthOrPercentage, Normal>; > > /// A type for possible values for min- and max- flavors of width, height, > /// block-size, and inline-size. > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum ExtremumLength { > MozMaxContent, > MozMinContent, > MozFitContent, > MozAvailable, > } > > impl ExtremumLength { >@@ -931,34 +953,34 @@ impl ExtremumLength { > /// > /// TODO: After these values are supported for both axes (and maybe > /// unprefixed, see bug 1322780) all this complexity can go away, and > /// everything can be derived (no need for uncacheable stuff). > fn valid_for(&self, wm: WritingMode, longhand: LonghandId) -> bool { > // We only make sense on the inline axis. > match longhand { > // FIXME(emilio): The flex-basis thing is not quite clear... >- LonghandId::FlexBasis | >- LonghandId::MinWidth | >- LonghandId::MaxWidth | >- LonghandId::Width => !wm.is_vertical(), >+ LonghandId::FlexBasis >+ | LonghandId::MinWidth >+ | LonghandId::MaxWidth >+ | LonghandId::Width => !wm.is_vertical(), > > LonghandId::MinHeight | LonghandId::MaxHeight | LonghandId::Height => wm.is_vertical(), > > LonghandId::MinInlineSize | LonghandId::MaxInlineSize | LonghandId::InlineSize => true, > // The block-* properties are rejected at parse-time, so they're > // unexpected here. > _ => { > debug_assert!( > false, > "Unexpected property using ExtremumLength: {:?}", > longhand, > ); > false >- }, >+ } > } > } > } > > /// A value suitable for a `min-width`, `min-height`, `width` or `height` > /// property. > /// > /// See values/specified/length.rs for more details. >@@ -986,42 +1008,42 @@ impl ToComputedValue for specified::MozLength { > fn to_computed_value(&self, context: &Context) -> MozLength { > debug_assert!( > context.for_non_inherited_property.is_some(), > "Someone added a MozLength to an inherited property? Evil!" > ); > match *self { > specified::MozLength::LengthOrPercentageOrAuto(ref lopoa) => { > MozLength::LengthOrPercentageOrAuto(lopoa.to_computed_value(context)) >- }, >+ } > specified::MozLength::ExtremumLength(ext) => { > context > .rule_cache_conditions > .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if !ext.valid_for( > context.builder.writing_mode, > context.for_non_inherited_property.unwrap(), > ) { > MozLength::auto() > } else { > MozLength::ExtremumLength(ext) > } >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &MozLength) -> Self { > match *computed { > MozLength::LengthOrPercentageOrAuto(ref lopoa) => { > specified::MozLength::LengthOrPercentageOrAuto( > specified::LengthOrPercentageOrAuto::from_computed_value(lopoa), > ) >- }, >+ } > MozLength::ExtremumLength(ext) => specified::MozLength::ExtremumLength(ext), > } > } > } > > /// A value suitable for a `max-width` or `max-height` property. > /// See values/specified/length.rs for more details. > #[allow(missing_docs)] >@@ -1048,38 +1070,38 @@ impl ToComputedValue for specified::MaxLength { > fn to_computed_value(&self, context: &Context) -> MaxLength { > debug_assert!( > context.for_non_inherited_property.is_some(), > "Someone added a MaxLength to an inherited property? Evil!" > ); > match *self { > specified::MaxLength::LengthOrPercentageOrNone(ref lopon) => { > MaxLength::LengthOrPercentageOrNone(lopon.to_computed_value(context)) >- }, >+ } > specified::MaxLength::ExtremumLength(ext) => { > context > .rule_cache_conditions > .borrow_mut() > .set_writing_mode_dependency(context.builder.writing_mode); > if !ext.valid_for( > context.builder.writing_mode, > context.for_non_inherited_property.unwrap(), > ) { > MaxLength::none() > } else { > MaxLength::ExtremumLength(ext) > } >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &MaxLength) -> Self { > match *computed { > MaxLength::LengthOrPercentageOrNone(ref lopon) => { > specified::MaxLength::LengthOrPercentageOrNone( > specified::LengthOrPercentageOrNone::from_computed_value(&lopon), > ) >- }, >+ } > MaxLength::ExtremumLength(ref ext) => specified::MaxLength::ExtremumLength(ext.clone()), > } > } > } >diff --git a/servo/components/style/values/computed/list.rs b/servo/components/style/values/computed/list.rs >index 0924cfc96fae..d70b1e77e7be 100644 >--- a/servo/components/style/values/computed/list.rs >+++ b/servo/components/style/values/computed/list.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! `list` computed values. > >-pub use values::specified::list::Quotes; > #[cfg(feature = "gecko")] > pub use values::specified::list::ListStyleType; >+pub use values::specified::list::Quotes; > > impl Quotes { > /// Initial value for `quotes`. > /// > /// FIXME(emilio): This should ideally not allocate. > #[inline] > pub fn get_initial_value() -> Quotes { > Quotes( >diff --git a/servo/components/style/values/computed/mod.rs b/servo/components/style/values/computed/mod.rs >index 9a6b5fd76b58..95e6e264be96 100644 >--- a/servo/components/style/values/computed/mod.rs >+++ b/servo/components/style/values/computed/mod.rs >@@ -1,90 +1,100 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed values. > >-use Atom; >-#[cfg(feature = "servo")] >-use Prefix; >+use super::animated::ToAnimatedValue; >+use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; >+use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; >+use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; >+use super::generics::{GreaterThanOrEqualToOne, NonNegative}; >+use super::specified; >+use super::{CSSFloat, CSSInteger}; > use context::QuirksMode; > use euclid::Size2D; > use font_metrics::{get_metrics_provider_for_product, FontMetricsProvider}; > use media_queries::Device; > #[cfg(feature = "gecko")] > use properties; > use properties::{ComputedValues, LonghandId, StyleBuilder}; > use rule_cache::RuleCacheConditions; > use std::cell::RefCell; > use std::cmp; > use std::f32; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ToCss}; > use style_traits::cursor::CursorKind; >-use super::{CSSFloat, CSSInteger}; >-use super::animated::ToAnimatedValue; >-use super::generics::{GreaterThanOrEqualToOne, NonNegative}; >-use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; >-use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; >-use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; >-use super::specified; >+use style_traits::{CssWriter, ToCss}; >+use Atom; >+#[cfg(feature = "servo")] >+use Prefix; > >-pub use app_units::Au; > #[cfg(feature = "gecko")] > pub use self::align::{AlignContent, AlignItems, JustifyContent, JustifyItems, SelfAlignment}; > #[cfg(feature = "gecko")] > pub use self::align::{AlignSelf, JustifySelf}; > pub use self::angle::Angle; > pub use self::background::{BackgroundRepeat, BackgroundSize}; >-pub use self::border::{BorderImageRepeat, BorderImageSideWidth, BorderImageSlice, BorderImageWidth}; > pub use self::border::{BorderCornerRadius, BorderRadius, BorderSpacing}; >-pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight}; >-pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; >-pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; >-pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; >-pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty}; >+pub use self::border::{ >+ BorderImageRepeat, BorderImageSideWidth, BorderImageSlice, BorderImageWidth, >+}; >+pub use self::box_::{ >+ AnimationIterationCount, AnimationName, Contain, Display, TransitionProperty, >+}; > pub use self::box_::{Appearance, Clear, Float}; > pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize}; > pub use self::box_::{ScrollSnapType, TouchAction, VerticalAlign, WillChange}; > pub use self::color::{Color, ColorPropertyValue, RGBAColor}; > pub use self::column::ColumnCount; > pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; > pub use self::effects::{BoxShadow, Filter, SimpleShadow}; > pub use self::flex::FlexBasis; >-pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; >+pub use self::font::{ >+ FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings, >+}; >+pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; >+pub use self::font::{ >+ FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight, >+}; >+pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; > #[cfg(feature = "gecko")] > pub use self::gecko::ScrollSnapPoint; >-pub use self::rect::LengthOrNumberRect; >-pub use self::resolution::Resolution; >-pub use super::{Auto, Either, None_}; >-pub use super::specified::{BorderStyle, TextDecorationLine}; >+pub use self::image::{Gradient, GradientItem, Image, ImageLayer, LineDirection, MozImageRect}; >+pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; > pub use self::length::{CalcLengthOrPercentage, Length, LengthOrNumber, LengthOrPercentage}; > pub use self::length::{LengthOrPercentageOrAuto, LengthOrPercentageOrNone, MaxLength, MozLength}; >-pub use self::length::{CSSPixelLength, ExtremumLength, NonNegativeLength}; > pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercentageOrAuto}; >-pub use self::list::Quotes; > #[cfg(feature = "gecko")] > pub use self::list::ListStyleType; >+pub use self::list::Quotes; > pub use self::outline::OutlineStyle; >-pub use self::percentage::{Percentage, NonNegativePercentage}; >+pub use self::percentage::{NonNegativePercentage, Percentage}; > pub use self::position::{GridAutoFlow, GridTemplateAreas, Position, ZIndex}; >+pub use self::rect::LengthOrNumberRect; >+pub use self::resolution::Resolution; >+pub use self::svg::MozContextProperties; > pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; > pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; >-pub use self::svg::MozContextProperties; > pub use self::table::XSpan; > pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize}; >-pub use self::text::{TextAlign, TextEmphasisPosition, TextEmphasisStyle, TextOverflow, WordSpacing}; >+pub use self::text::{ >+ TextAlign, TextEmphasisPosition, TextEmphasisStyle, TextOverflow, WordSpacing, >+}; > pub use self::time::Time; > pub use self::transform::{Rotate, Scale, TimingFunction, Transform, TransformOperation}; > pub use self::transform::{TransformOrigin, TransformStyle, Translate}; >-pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon}; > #[cfg(feature = "gecko")] > pub use self::ui::CursorImage; >+pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon}; >+pub use super::specified::{BorderStyle, TextDecorationLine}; >+pub use super::{Auto, Either, None_}; >+pub use app_units::Au; > > #[cfg(feature = "gecko")] > pub mod align; > pub mod angle; > pub mod background; > pub mod basic_shape; > pub mod border; > #[path = "box.rs"] >@@ -521,33 +531,33 @@ pub enum NumberOrPercentage { > impl ToComputedValue for specified::NumberOrPercentage { > type ComputedValue = NumberOrPercentage; > > #[inline] > fn to_computed_value(&self, context: &Context) -> NumberOrPercentage { > match *self { > specified::NumberOrPercentage::Percentage(percentage) => { > NumberOrPercentage::Percentage(percentage.to_computed_value(context)) >- }, >+ } > specified::NumberOrPercentage::Number(number) => { > NumberOrPercentage::Number(number.to_computed_value(context)) >- }, >+ } > } > } > #[inline] > fn from_computed_value(computed: &NumberOrPercentage) -> Self { > match *computed { > NumberOrPercentage::Percentage(percentage) => { > specified::NumberOrPercentage::Percentage(ToComputedValue::from_computed_value( > &percentage, > )) >- }, >+ } > NumberOrPercentage::Number(number) => { > specified::NumberOrPercentage::Number(ToComputedValue::from_computed_value(&number)) >- }, >+ } > } > } > } > > /// A type used for opacity. > pub type Opacity = CSSFloat; > > /// A `<integer>` value. >diff --git a/servo/components/style/values/computed/percentage.rs b/servo/components/style/values/computed/percentage.rs >index 718d74335b7f..6e6264c969af 100644 >--- a/servo/components/style/values/computed/percentage.rs >+++ b/servo/components/style/values/computed/percentage.rs >@@ -1,25 +1,37 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed percentages. > > use std::fmt; > use style_traits::{CssWriter, ToCss}; >-use values::{serialize_percentage, CSSFloat}; > use values::animated::ToAnimatedValue; > use values::generics::NonNegative; >+use values::{serialize_percentage, CSSFloat}; > > /// A computed percentage. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, Default, >- MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, >- ToAnimatedValue, ToAnimatedZero, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ Default, >+ MallocSizeOf, >+ PartialEq, >+ PartialOrd, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+)] > pub struct Percentage(pub CSSFloat); > > impl Percentage { > /// 0% > #[inline] > pub fn zero() -> Self { > Percentage(0.) > } >diff --git a/servo/components/style/values/computed/resolution.rs b/servo/components/style/values/computed/resolution.rs >index d90bdf4867df..9d743f9cbf3e 100644 >--- a/servo/components/style/values/computed/resolution.rs >+++ b/servo/components/style/values/computed/resolution.rs >@@ -3,19 +3,19 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Resolution values: > //! > //! https://drafts.csswg.org/css-values/#resolution > > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; >-use values::CSSFloat; > use values::computed::{Context, ToComputedValue}; > use values::specified; >+use values::CSSFloat; > > /// A computed `<resolution>`. > pub struct Resolution(CSSFloat); > > impl Resolution { > /// Returns this resolution value as dppx. > #[inline] > pub fn dppx(&self) -> CSSFloat { >diff --git a/servo/components/style/values/computed/svg.rs b/servo/components/style/values/computed/svg.rs >index ab9bbd18b4ef..375da2eeeaab 100644 >--- a/servo/components/style/values/computed/svg.rs >+++ b/servo/components/style/values/computed/svg.rs >@@ -1,22 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for SVG properties. > > use app_units::Au; >-use values::RGBA; >-use values::computed::{LengthOrPercentage, NonNegativeLength}; >-use values::computed::{NonNegativeLengthOrPercentage, NonNegativeNumber, Number}; >-use values::computed::Opacity; > use values::computed::color::Color; > use values::computed::url::ComputedUrl; >+use values::computed::Opacity; >+use values::computed::{LengthOrPercentage, NonNegativeLength}; >+use values::computed::{NonNegativeLengthOrPercentage, NonNegativeNumber, Number}; > use values::generics::svg as generic; >+use values::RGBA; > > pub use values::specified::SVGPaintOrder; > > pub use values::specified::MozContextProperties; > > /// Computed SVG Paint value > pub type SVGPaint = generic::SVGPaint<Color, ComputedUrl>; > /// Computed SVG Paint Kind value >@@ -63,20 +63,20 @@ impl From<Au> for SVGLength { > pub type NonNegativeSvgLengthOrPercentageOrNumber = > generic::SvgLengthOrPercentageOrNumber<NonNegativeLengthOrPercentage, NonNegativeNumber>; > > impl Into<NonNegativeSvgLengthOrPercentageOrNumber> for SvgLengthOrPercentageOrNumber { > fn into(self) -> NonNegativeSvgLengthOrPercentageOrNumber { > match self { > generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { > generic::SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop.into()) >- }, >+ } > generic::SvgLengthOrPercentageOrNumber::Number(num) => { > generic::SvgLengthOrPercentageOrNumber::Number(num.into()) >- }, >+ } > } > } > } > > /// An non-negative wrapper of SVGLength. > pub type SVGWidth = generic::SVGLength<NonNegativeSvgLengthOrPercentageOrNumber>; > > impl From<NonNegativeLength> for SVGWidth { >diff --git a/servo/components/style/values/computed/text.rs b/servo/components/style/values/computed/text.rs >index b41ecdb7e678..f8443ec607ac 100644 >--- a/servo/components/style/values/computed/text.rs >+++ b/servo/components/style/values/computed/text.rs >@@ -3,24 +3,24 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for text properties. > > #[cfg(feature = "servo")] > use properties::StyleBuilder; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; >-use values::{CSSFloat, CSSInteger}; >-use values::computed::{NonNegativeLength, NonNegativeNumber}; > use values::computed::length::{Length, LengthOrPercentage}; >+use values::computed::{NonNegativeLength, NonNegativeNumber}; > use values::generics::text::InitialLetter as GenericInitialLetter; > use values::generics::text::LineHeight as GenericLineHeight; > use values::generics::text::MozTabSize as GenericMozTabSize; > use values::generics::text::Spacing; > use values::specified::text::{TextEmphasisFillMode, TextEmphasisShapeKeyword, TextOverflowSide}; >+use values::{CSSFloat, CSSInteger}; > > pub use values::specified::TextAlignKeyword as TextAlign; > pub use values::specified::TextEmphasisPosition; > > /// A computed value for the `initial-letter` property. > pub type InitialLetter = GenericInitialLetter<CSSFloat, CSSInteger>; > > /// A computed value for the `letter-spacing` property. >diff --git a/servo/components/style/values/computed/transform.rs b/servo/components/style/values/computed/transform.rs >index bbf710c42956..8bdbdef6f676 100644 >--- a/servo/components/style/values/computed/transform.rs >+++ b/servo/components/style/values/computed/transform.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed types for CSS values that are related to transformations. > >+use super::CSSFloat; > use euclid::{Transform3D, Vector3D}; > use num_traits::Zero; >-use super::CSSFloat; > use values::animated::ToAnimatedZero; > use values::computed::{Angle, Integer, Length, LengthOrPercentage, Number, Percentage}; > use values::generics::transform as generic; > > pub use values::generics::transform::TransformStyle; > > /// A single operation in a computed CSS `transform` > pub type TransformOperation = >@@ -118,53 +118,53 @@ impl From<Transform3D<CSSFloat>> for Matrix3D { > > impl TransformOperation { > /// Convert to a Translate3D. > /// > /// Must be called on a Translate function > pub fn to_translate_3d(&self) -> Self { > match *self { > generic::TransformOperation::Translate3D(..) => self.clone(), >- generic::TransformOperation::TranslateX(ref x) | >- generic::TransformOperation::Translate(ref x, None) => { >+ generic::TransformOperation::TranslateX(ref x) >+ | generic::TransformOperation::Translate(ref x, None) => { > generic::TransformOperation::Translate3D( > x.clone(), > LengthOrPercentage::zero(), > Length::zero(), > ) >- }, >+ } > generic::TransformOperation::Translate(ref x, Some(ref y)) => { > generic::TransformOperation::Translate3D(x.clone(), y.clone(), Length::zero()) >- }, >+ } > generic::TransformOperation::TranslateY(ref y) => { > generic::TransformOperation::Translate3D( > LengthOrPercentage::zero(), > y.clone(), > Length::zero(), > ) >- }, >+ } > generic::TransformOperation::TranslateZ(ref z) => { > generic::TransformOperation::Translate3D( > LengthOrPercentage::zero(), > LengthOrPercentage::zero(), > z.clone(), > ) >- }, >+ } > _ => unreachable!(), > } > } > > /// Convert to a Rotate3D. > /// > /// Must be called on a Rotate function. > pub fn to_rotate_3d(&self) -> Self { > match *self { > generic::TransformOperation::Rotate3D(..) => self.clone(), >- generic::TransformOperation::RotateZ(ref angle) | >- generic::TransformOperation::Rotate(ref angle) => { >+ generic::TransformOperation::RotateZ(ref angle) >+ | generic::TransformOperation::Rotate(ref angle) => { > generic::TransformOperation::Rotate3D(0., 0., 1., angle.clone()) > } > generic::TransformOperation::RotateX(ref angle) => { > generic::TransformOperation::Rotate3D(1., 0., 0., angle.clone()) > } > generic::TransformOperation::RotateY(ref angle) => { > generic::TransformOperation::Rotate3D(0., 1., 0., angle.clone()) > } >@@ -175,190 +175,192 @@ impl TransformOperation { > /// Convert to a Scale3D. > /// > /// Must be called on a Scale function > pub fn to_scale_3d(&self) -> Self { > match *self { > generic::TransformOperation::Scale3D(..) => self.clone(), > generic::TransformOperation::Scale(s, None) => { > generic::TransformOperation::Scale3D(s, s, 1.) >- }, >+ } > generic::TransformOperation::Scale(x, Some(y)) => { > generic::TransformOperation::Scale3D(x, y, 1.) >- }, >+ } > generic::TransformOperation::ScaleX(x) => { > generic::TransformOperation::Scale3D(x, 1., 1.) >- }, >+ } > generic::TransformOperation::ScaleY(y) => { > generic::TransformOperation::Scale3D(1., y, 1.) >- }, >+ } > generic::TransformOperation::ScaleZ(z) => { > generic::TransformOperation::Scale3D(1., 1., z) >- }, >+ } > _ => unreachable!(), > } > } > } > > /// Build an equivalent 'identity transform function list' based > /// on an existing transform list. > /// http://dev.w3.org/csswg/css-transforms/#none-transform-animation > impl ToAnimatedZero for TransformOperation { > fn to_animated_zero(&self) -> Result<Self, ()> { > match *self { > generic::TransformOperation::Matrix3D(..) => { > Ok(generic::TransformOperation::Matrix3D(Matrix3D::identity())) >- }, >+ } > generic::TransformOperation::Matrix(..) => { > Ok(generic::TransformOperation::Matrix(Matrix::identity())) >- }, >+ } > generic::TransformOperation::Skew(sx, sy) => Ok(generic::TransformOperation::Skew( > sx.to_animated_zero()?, > sy.to_animated_zero()?, > )), > generic::TransformOperation::SkewX(s) => { > Ok(generic::TransformOperation::SkewX(s.to_animated_zero()?)) >- }, >+ } > generic::TransformOperation::SkewY(s) => { > Ok(generic::TransformOperation::SkewY(s.to_animated_zero()?)) >- }, >+ } > generic::TransformOperation::Translate3D(ref tx, ref ty, ref tz) => { > Ok(generic::TransformOperation::Translate3D( > tx.to_animated_zero()?, > ty.to_animated_zero()?, > tz.to_animated_zero()?, > )) >- }, >+ } > generic::TransformOperation::Translate(ref tx, ref ty) => { > Ok(generic::TransformOperation::Translate( > tx.to_animated_zero()?, > ty.to_animated_zero()?, > )) >- }, >+ } > generic::TransformOperation::TranslateX(ref t) => Ok( > generic::TransformOperation::TranslateX(t.to_animated_zero()?), > ), > generic::TransformOperation::TranslateY(ref t) => Ok( > generic::TransformOperation::TranslateY(t.to_animated_zero()?), > ), > generic::TransformOperation::TranslateZ(ref t) => Ok( > generic::TransformOperation::TranslateZ(t.to_animated_zero()?), > ), > generic::TransformOperation::Scale3D(..) => { > Ok(generic::TransformOperation::Scale3D(1.0, 1.0, 1.0)) >- }, >+ } > generic::TransformOperation::Scale(_, _) => { > Ok(generic::TransformOperation::Scale(1.0, Some(1.0))) >- }, >+ } > generic::TransformOperation::ScaleX(..) => Ok(generic::TransformOperation::ScaleX(1.0)), > generic::TransformOperation::ScaleY(..) => Ok(generic::TransformOperation::ScaleY(1.0)), > generic::TransformOperation::ScaleZ(..) => Ok(generic::TransformOperation::ScaleZ(1.0)), > generic::TransformOperation::Rotate3D(x, y, z, a) => { > let (x, y, z, _) = generic::get_normalized_vector_and_angle(x, y, z, a); > Ok(generic::TransformOperation::Rotate3D( > x, > y, > z, > Angle::zero(), > )) >- }, >+ } > generic::TransformOperation::RotateX(_) => { > Ok(generic::TransformOperation::RotateX(Angle::zero())) >- }, >+ } > generic::TransformOperation::RotateY(_) => { > Ok(generic::TransformOperation::RotateY(Angle::zero())) >- }, >+ } > generic::TransformOperation::RotateZ(_) => { > Ok(generic::TransformOperation::RotateZ(Angle::zero())) >- }, >+ } > generic::TransformOperation::Rotate(_) => { > Ok(generic::TransformOperation::Rotate(Angle::zero())) >- }, >- generic::TransformOperation::Perspective(ref l) => { >- Ok(generic::TransformOperation::Perspective(l.to_animated_zero()?)) >- }, >- generic::TransformOperation::AccumulateMatrix { .. } | >- generic::TransformOperation::InterpolateMatrix { .. } => { >+ } >+ generic::TransformOperation::Perspective(ref l) => Ok( >+ generic::TransformOperation::Perspective(l.to_animated_zero()?), >+ ), >+ generic::TransformOperation::AccumulateMatrix { .. } >+ | generic::TransformOperation::InterpolateMatrix { .. } => { > // AccumulateMatrix/InterpolateMatrix: We do interpolation on > // AccumulateMatrix/InterpolateMatrix by reading it as a ComputedMatrix > // (with layout information), and then do matrix interpolation. > // > // Therefore, we use an identity matrix to represent the identity transform list. > // http://dev.w3.org/csswg/css-transforms/#identity-transform-function > Ok(generic::TransformOperation::Matrix3D(Matrix3D::identity())) >- }, >+ } > } > } > } > > impl ToAnimatedZero for Transform { > #[inline] > fn to_animated_zero(&self) -> Result<Self, ()> { >- Ok(generic::Transform(self.0 >- .iter() >- .map(|op| op.to_animated_zero()) >- .collect::<Result<Vec<_>, _>>()?)) >+ Ok(generic::Transform( >+ self.0 >+ .iter() >+ .map(|op| op.to_animated_zero()) >+ .collect::<Result<Vec<_>, _>>()?, >+ )) > } > } > > /// A computed CSS `rotate` > pub type Rotate = generic::Rotate<Number, Angle>; > > impl Rotate { > /// Convert TransformOperation to Rotate. > pub fn to_transform_operation(&self) -> Option<TransformOperation> { > match *self { > generic::Rotate::None => None, > generic::Rotate::Rotate(angle) => Some(generic::TransformOperation::Rotate(angle)), > generic::Rotate::Rotate3D(rx, ry, rz, angle) => { > Some(generic::TransformOperation::Rotate3D(rx, ry, rz, angle)) >- }, >+ } > } > } > > /// Convert Rotate to TransformOperation. > pub fn from_transform_operation(operation: &TransformOperation) -> Rotate { > match *operation { > generic::TransformOperation::Rotate(angle) => generic::Rotate::Rotate(angle), > generic::TransformOperation::Rotate3D(rx, ry, rz, angle) => { > generic::Rotate::Rotate3D(rx, ry, rz, angle) >- }, >+ } > _ => unreachable!("Found unexpected value for rotate property"), > } > } > } > > /// A computed CSS `translate` > pub type Translate = generic::Translate<LengthOrPercentage, Length>; > > impl Translate { > /// Convert TransformOperation to Translate. > pub fn to_transform_operation(&self) -> Option<TransformOperation> { > match *self { > generic::Translate::None => None, > generic::Translate::TranslateX(tx) => Some(generic::TransformOperation::TranslateX(tx)), > generic::Translate::Translate(tx, ty) => { > Some(generic::TransformOperation::Translate(tx, Some(ty))) >- }, >+ } > generic::Translate::Translate3D(tx, ty, tz) => { > Some(generic::TransformOperation::Translate3D(tx, ty, tz)) >- }, >+ } > } > } > > /// Convert Translate to TransformOperation. > pub fn from_transform_operation(operation: &TransformOperation) -> Translate { > match *operation { > generic::TransformOperation::TranslateX(tx) => generic::Translate::TranslateX(tx), > generic::TransformOperation::Translate(tx, Some(ty)) => { > generic::Translate::Translate(tx, ty) >- }, >+ } > generic::TransformOperation::Translate3D(tx, ty, tz) => { > generic::Translate::Translate3D(tx, ty, tz) >- }, >+ } > _ => unreachable!("Found unexpected value for translate"), > } > } > } > > /// A computed CSS `scale` > pub type Scale = generic::Scale<Number>; > >@@ -366,17 +368,17 @@ impl Scale { > /// Convert TransformOperation to Scale. > pub fn to_transform_operation(&self) -> Option<TransformOperation> { > match *self { > generic::Scale::None => None, > generic::Scale::ScaleX(sx) => Some(generic::TransformOperation::ScaleX(sx)), > generic::Scale::Scale(sx, sy) => Some(generic::TransformOperation::Scale(sx, Some(sy))), > generic::Scale::Scale3D(sx, sy, sz) => { > Some(generic::TransformOperation::Scale3D(sx, sy, sz)) >- }, >+ } > } > } > > /// Convert Scale to TransformOperation. > pub fn from_transform_operation(operation: &TransformOperation) -> Scale { > match *operation { > generic::TransformOperation::ScaleX(sx) => generic::Scale::ScaleX(sx), > generic::TransformOperation::Scale(sx, Some(sy)) => generic::Scale::Scale(sx, sy), >diff --git a/servo/components/style/values/computed/ui.rs b/servo/components/style/values/computed/ui.rs >index 5307f79a38e1..1639069fdf46 100644 >--- a/servo/components/style/values/computed/ui.rs >+++ b/servo/components/style/values/computed/ui.rs >@@ -1,19 +1,19 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Computed values for UI properties > >-use values::{Auto, Either}; >-use values::computed::Number; > use values::computed::color::Color; > use values::computed::url::ComputedImageUrl; >+use values::computed::Number; > use values::generics::ui as generics; >+use values::{Auto, Either}; > > pub use values::specified::ui::MozForceBrokenImageIcon; > > /// auto | <color> > pub type ColorOrAuto = Either<Color, Auto>; > > /// A computed value for the `cursor` property. > pub type Cursor = generics::Cursor<CursorImage>; >diff --git a/servo/components/style/values/computed/url.rs b/servo/components/style/values/computed/url.rs >index cf9577101822..aca5d301fd25 100644 >--- a/servo/components/style/values/computed/url.rs >+++ b/servo/components/style/values/computed/url.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Common handling for the computed value CSS url() values. > > use values::generics::url::UrlOrNone as GenericUrlOrNone; > >-#[cfg(feature = "servo")] >-pub use servo::url::{ComputedImageUrl, ComputedUrl}; > #[cfg(feature = "gecko")] > pub use gecko::url::{ComputedImageUrl, ComputedUrl}; >+#[cfg(feature = "servo")] >+pub use servo::url::{ComputedImageUrl, ComputedUrl}; > > /// Computed <url> | <none> > pub type UrlOrNone = GenericUrlOrNone<ComputedUrl>; > > /// Computed image <url> | <none> > pub type ImageUrlOrNone = GenericUrlOrNone<ComputedImageUrl>; >diff --git a/servo/components/style/values/distance.rs b/servo/components/style/values/distance.rs >index fbdd4ea00043..c2827c4ece9e 100644 >--- a/servo/components/style/values/distance.rs >+++ b/servo/components/style/values/distance.rs >@@ -96,18 +96,18 @@ where > } > > impl<T> ComputeSquaredDistance for Size2D<T> > where > T: ComputeSquaredDistance, > { > #[inline] > fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { >- Ok(self.width.compute_squared_distance(&other.width)? + >- self.height.compute_squared_distance(&other.height)?) >+ Ok(self.width.compute_squared_distance(&other.width)? >+ + self.height.compute_squared_distance(&other.height)?) > } > } > > impl SquaredDistance { > /// Returns the square root of this squared distance. > #[inline] > pub fn sqrt(self) -> f64 { > self.value.sqrt() >diff --git a/servo/components/style/values/generics/background.rs b/servo/components/style/values/generics/background.rs >index b25b00514d02..a4f4c58d8cd3 100644 >--- a/servo/components/style/values/generics/background.rs >+++ b/servo/components/style/values/generics/background.rs >@@ -1,18 +1,29 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS values related to backgrounds. > > /// A generic value for the `background-size` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum BackgroundSize<LengthOrPercentageOrAuto> { > /// `<width> <height>` > Explicit { > /// Explicit width. > width: LengthOrPercentageOrAuto, > /// Explicit height. > height: LengthOrPercentageOrAuto, > }, >diff --git a/servo/components/style/values/generics/basic_shape.rs b/servo/components/style/values/generics/basic_shape.rs >index 3bad738c1e61..dc2ac6562307 100644 >--- a/servo/components/style/values/generics/basic_shape.rs >+++ b/servo/components/style/values/generics/basic_shape.rs >@@ -13,129 +13,196 @@ use values::generics::border::BorderRadius; > use values::generics::position::Position; > use values::generics::rect::Rect; > > /// A clipping shape, for `clip-path`. > pub type ClippingShape<BasicShape, Url> = ShapeSource<BasicShape, GeometryBox, Url>; > > /// <https://drafts.fxtf.org/css-masking-1/#typedef-geometry-box> > #[allow(missing_docs)] >-#[derive(Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum GeometryBox { > FillBox, > StrokeBox, > ViewBox, > ShapeBox(ShapeBox), > } > > /// A float area shape, for `shape-outside`. > pub type FloatAreaShape<BasicShape, Image> = ShapeSource<BasicShape, ShapeBox, Image>; > > /// https://drafts.csswg.org/css-shapes-1/#typedef-shape-box > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum ShapeBox { > MarginBox, > BorderBox, > PaddingBox, > ContentBox, > } > > /// A shape source, for some reference box. > #[allow(missing_docs)] > #[animation(no_bound(ImageOrUrl))] >-#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum ShapeSource<BasicShape, ReferenceBox, ImageOrUrl> { > #[animation(error)] > ImageOrUrl(ImageOrUrl), > Shape(BasicShape, Option<ReferenceBox>), > #[animation(error)] > Box(ReferenceBox), > #[animation(error)] > None, > } > > #[allow(missing_docs)] >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum BasicShape<H, V, LengthOrPercentage> { > Inset(#[css(field_bound)] InsetRect<LengthOrPercentage>), > Circle(#[css(field_bound)] Circle<H, V, LengthOrPercentage>), > Ellipse(#[css(field_bound)] Ellipse<H, V, LengthOrPercentage>), > Polygon(Polygon<LengthOrPercentage>), > } > > /// <https://drafts.csswg.org/css-shapes/#funcdef-inset> > #[allow(missing_docs)] > #[css(function = "inset")] >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+)] > pub struct InsetRect<LengthOrPercentage> { > pub rect: Rect<LengthOrPercentage>, > pub round: Option<BorderRadius<LengthOrPercentage>>, > } > > /// <https://drafts.csswg.org/css-shapes/#funcdef-circle> > #[allow(missing_docs)] > #[css(function)] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+)] > pub struct Circle<H, V, LengthOrPercentage> { > pub position: Position<H, V>, > pub radius: ShapeRadius<LengthOrPercentage>, > } > > /// <https://drafts.csswg.org/css-shapes/#funcdef-ellipse> > #[allow(missing_docs)] > #[css(function)] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+)] > pub struct Ellipse<H, V, LengthOrPercentage> { > pub position: Position<H, V>, > pub semiaxis_x: ShapeRadius<LengthOrPercentage>, > pub semiaxis_y: ShapeRadius<LengthOrPercentage>, > } > > /// <https://drafts.csswg.org/css-shapes/#typedef-shape-radius> > #[allow(missing_docs)] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum ShapeRadius<LengthOrPercentage> { > Length(LengthOrPercentage), > #[animation(error)] > ClosestSide, > #[animation(error)] > FarthestSide, > } > > /// A generic type for representing the `polygon()` function > /// > /// <https://drafts.csswg.org/css-shapes/#funcdef-polygon> > #[css(function)] >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct Polygon<LengthOrPercentage> { > /// The filling rule for a polygon. > pub fill: FillRule, > /// A collection of (x, y) coordinates to draw the polygon. > pub coordinates: Vec<(LengthOrPercentage, LengthOrPercentage)>, > } > > // https://drafts.csswg.org/css-shapes/#typedef-fill-rule > // NOTE: Basic shapes spec says that these are the only two values, however > // https://www.w3.org/TR/SVG/painting.html#FillRuleProperty > // says that it can also be `inherit` > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum FillRule { > Nonzero, > Evenodd, > } > > // FIXME(nox): Implement ComputeSquaredDistance for T types and stop > // using PartialEq here, this will let us derive this impl. > impl<B, T, U> ComputeSquaredDistance for ShapeSource<B, T, U> >@@ -143,20 +210,21 @@ where > B: ComputeSquaredDistance, > T: PartialEq, > { > fn compute_squared_distance(&self, other: &Self) -> Result<SquaredDistance, ()> { > match (self, other) { > ( > &ShapeSource::Shape(ref this, ref this_box), > &ShapeSource::Shape(ref other, ref other_box), >- ) if this_box == other_box => >+ ) >+ if this_box == other_box => > { > this.compute_squared_distance(other) >- }, >+ } > _ => Err(()), > } > } > } > > impl<B, T, U> ToAnimatedZero for ShapeSource<B, T, U> { > fn to_animated_zero(&self) -> Result<Self, ()> { > Err(()) >@@ -194,26 +262,26 @@ where > { > fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> { > if self.fill != other.fill { > return Err(()); > } > if self.coordinates.len() != other.coordinates.len() { > return Err(()); > } >- let coordinates = self.coordinates >+ let coordinates = self >+ .coordinates > .iter() > .zip(other.coordinates.iter()) > .map(|(this, other)| { > Ok(( > this.0.animate(&other.0, procedure)?, > this.1.animate(&other.1, procedure)?, > )) >- }) >- .collect::<Result<Vec<_>, _>>()?; >+ }).collect::<Result<Vec<_>, _>>()?; > Ok(Polygon { > fill: self.fill, > coordinates, > }) > } > } > > impl<L> ComputeSquaredDistance for Polygon<L> >@@ -229,18 +297,17 @@ where > } > self.coordinates > .iter() > .zip(other.coordinates.iter()) > .map(|(this, other)| { > let d1 = this.0.compute_squared_distance(&other.0)?; > let d2 = this.1.compute_squared_distance(&other.1)?; > Ok(d1 + d2) >- }) >- .sum() >+ }).sum() > } > } > > impl<L: ToCss> ToCss for Polygon<L> { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { >diff --git a/servo/components/style/values/generics/border.rs b/servo/components/style/values/generics/border.rs >index c25560ed0f15..5ed7fbdee98c 100644 >--- a/servo/components/style/values/generics/border.rs >+++ b/servo/components/style/values/generics/border.rs >@@ -5,69 +5,101 @@ > //! Generic types for CSS values related to borders. > > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; > use values::generics::rect::Rect; > use values::generics::size::Size; > > /// A generic value for a single side of a `border-image-width` property. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum BorderImageSideWidth<LengthOrPercentage, Number> { > /// `<length-or-percentage>` > Length(LengthOrPercentage), > /// `<number>` > Number(Number), > /// `auto` > Auto, > } > > /// A generic value for the `border-image-slice` property. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub struct BorderImageSlice<NumberOrPercentage> { > /// The offsets. > #[css(field_bound)] > pub offsets: Rect<NumberOrPercentage>, > /// Whether to fill the middle part. > #[css(represents_keyword)] > pub fill: bool, > } > > /// A generic value for the `border-*-radius` longhand properties. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub struct BorderCornerRadius<L>(#[css(field_bound)] pub Size<L>); > > impl<L> BorderCornerRadius<L> { > /// Trivially create a `BorderCornerRadius`. > pub fn new(w: L, h: L) -> Self { > BorderCornerRadius(Size::new(w, h)) > } > } > > /// A generic value for the `border-spacing` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub struct BorderSpacing<L>(#[css(field_bound)] pub Size<L>); > > impl<L> BorderSpacing<L> { > /// Trivially create a `BorderCornerRadius`. > pub fn new(w: L, h: L) -> Self { > BorderSpacing(Size::new(w, h)) > } > } > > /// A generic value for `border-radius`, `outline-radius` and `inset()`. > /// > /// <https://drafts.csswg.org/css-backgrounds-3/#border-radius> >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+)] > pub struct BorderRadius<LengthOrPercentage> { > /// The top left radius. > pub top_left: BorderCornerRadius<LengthOrPercentage>, > /// The top right radius. > pub top_right: BorderCornerRadius<LengthOrPercentage>, > /// The bottom right radius. > pub bottom_right: BorderCornerRadius<LengthOrPercentage>, > /// The bottom left radius. >@@ -115,18 +147,20 @@ where > widths: Rect<&L>, > heights: Rect<&L>, > dest: &mut CssWriter<W>, > ) -> fmt::Result > where > W: Write, > { > widths.to_css(dest)?; >- if widths.0 != heights.0 || widths.1 != heights.1 || widths.2 != heights.2 || >- widths.3 != heights.3 >+ if widths.0 != heights.0 >+ || widths.1 != heights.1 >+ || widths.2 != heights.2 >+ || widths.3 != heights.3 > { > dest.write_str(" / ")?; > heights.to_css(dest)?; > } > Ok(()) > } > } > >diff --git a/servo/components/style/values/generics/box.rs b/servo/components/style/values/generics/box.rs >index ea79e98eefb8..0b5259742887 100644 >--- a/servo/components/style/values/generics/box.rs >+++ b/servo/components/style/values/generics/box.rs >@@ -2,18 +2,28 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for box properties. > > use values::animated::ToAnimatedZero; > > /// A generic value for the `vertical-align` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum VerticalAlign<LengthOrPercentage> { > /// `baseline` > Baseline, > /// `sub` > Sub, > /// `super` > Super, > /// `top` >@@ -43,29 +53,39 @@ impl<L> VerticalAlign<L> { > > impl<L> ToAnimatedZero for VerticalAlign<L> { > fn to_animated_zero(&self) -> Result<Self, ()> { > Err(()) > } > } > > /// https://drafts.csswg.org/css-animations/#animation-iteration-count >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum AnimationIterationCount<Number> { > /// A `<number>` value. > Number(Number), > /// The `infinite` keyword. > Infinite, > } > > /// A generic value for the `perspective` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum Perspective<NonNegativeLength> { > /// A non-negative length. > Length(NonNegativeLength), > /// The keyword `none`. > None, > } > > impl<L> Perspective<L> { >diff --git a/servo/components/style/values/generics/column.rs b/servo/components/style/values/generics/column.rs >index 1d76f6cb552c..5f96650d3e8d 100644 >--- a/servo/components/style/values/generics/column.rs >+++ b/servo/components/style/values/generics/column.rs >@@ -1,18 +1,29 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for the column properties. > > /// A generic type for `column-count` values. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum ColumnCount<PositiveInteger> { > /// A positive integer. > Integer(PositiveInteger), > /// The keyword `auto`. > #[animation(error)] > Auto, > } > >diff --git a/servo/components/style/values/generics/counters.rs b/servo/components/style/values/generics/counters.rs >index 779d56d65ee9..a5990691336d 100644 >--- a/servo/components/style/values/generics/counters.rs >+++ b/servo/components/style/values/generics/counters.rs >@@ -2,35 +2,35 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for counters-related CSS values. > > #[cfg(feature = "servo")] > use computed_values::list_style_type::T as ListStyleType; > use std::ops::Deref; >-use values::CustomIdent; > #[cfg(feature = "gecko")] > use values::generics::CounterStyleOrNone; > #[cfg(feature = "gecko")] > use values::specified::Attr; >+use values::CustomIdent; > > /// A name / value pair for counters. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct CounterPair<Integer> { > /// The name of the counter. > pub name: CustomIdent, > /// The value of the counter / increment / etc. > pub value: Integer, > } > > /// A generic value for the `counter-increment` property. >-#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub struct CounterIncrement<I>(Counters<I>); > > impl<I> CounterIncrement<I> { > /// Returns a new value for `counter-increment`. > #[inline] > pub fn new(counters: Vec<CounterPair<I>>) -> Self { > CounterIncrement(Counters(counters.into_boxed_slice())) > } >@@ -41,18 +41,19 @@ impl<I> Deref for CounterIncrement<I> { > > #[inline] > fn deref(&self) -> &Self::Target { > &(self.0).0 > } > } > > /// A generic value for the `counter-reset` property. >-#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub struct CounterReset<I>(Counters<I>); > > impl<I> CounterReset<I> { > /// Returns a new value for `counter-reset`. > #[inline] > pub fn new(counters: Vec<CounterPair<I>>) -> Self { > CounterReset(Counters(counters.into_boxed_slice())) > } >@@ -65,18 +66,17 @@ impl<I> Deref for CounterReset<I> { > fn deref(&self) -> &Self::Target { > &(self.0).0 > } > } > > /// A generic value for lists of counters. > /// > /// Keyword `none` is represented by an empty vector. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct Counters<I>(#[css(iterable, if_empty = "none")] Box<[CounterPair<I>]>); > > impl<I> Default for Counters<I> { > #[inline] > fn default() -> Self { > Counters(vec![].into_boxed_slice()) > } > } >@@ -97,18 +97,17 @@ fn is_decimal(counter_type: &CounterStyleType) -> bool { > #[inline] > fn is_decimal(counter_type: &CounterStyleType) -> bool { > *counter_type == CounterStyleOrNone::decimal() > } > > /// The specified value for the `content` property. > /// > /// https://drafts.csswg.org/css-content/#propdef-content >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum Content<ImageUrl> { > /// `normal` reserved keyword. > Normal, > /// `none` reserved keyword. > None, > /// `-moz-alt-content`. > #[cfg(feature = "gecko")] > MozAltContent, >@@ -120,18 +119,17 @@ impl<ImageUrl> Content<ImageUrl> { > /// Set `content` property to `normal`. > #[inline] > pub fn normal() -> Self { > Content::Normal > } > } > > /// Items for the `content` property. >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum ContentItem<ImageUrl> { > /// Literal string content. > String(Box<str>), > /// `counter(name, style)`. > #[css(comma, function)] > Counter(CustomIdent, #[css(skip_if = "is_decimal")] CounterStyleType), > /// `counters(name, separator, style)`. > #[css(comma, function)] >diff --git a/servo/components/style/values/generics/effects.rs b/servo/components/style/values/generics/effects.rs >index f05dfe82d66f..7c7e3f4bef32 100644 >--- a/servo/components/style/values/generics/effects.rs >+++ b/servo/components/style/values/generics/effects.rs >@@ -1,33 +1,51 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS values related to effects. > > /// A generic value for a single `box-shadow`. >-#[derive(Animate, Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToAnimatedValue, ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToCss, >+)] > pub struct BoxShadow<Color, SizeLength, BlurShapeLength, ShapeLength> { > /// The base shadow. > pub base: SimpleShadow<Color, SizeLength, BlurShapeLength>, > /// The spread radius. > pub spread: ShapeLength, > /// Whether this is an inset box shadow. > #[animation(constant)] > #[css(represents_keyword)] > pub inset: bool, > } > > /// A generic value for a single `filter`. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > #[animation(no_bound(Url))] >-#[derive(Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToComputedValue, >+ ToCss, >+)] > pub enum Filter<Angle, Factor, Length, DropShadow, Url> { > /// `blur(<length>)` > #[css(function)] > Blur(Length), > /// `brightness(<factor>)` > #[css(function)] > Brightness(Factor), > /// `contrast(<factor>)` >@@ -58,18 +76,28 @@ pub enum Filter<Angle, Factor, Length, DropShadow, Url> { > #[animation(error)] > Url(Url), > } > > /// A generic value for the `drop-shadow()` filter and the `text-shadow` property. > /// > /// Contrary to the canonical order from the spec, the color is serialised > /// first, like in Gecko and Webkit. >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToCss, >+)] > pub struct SimpleShadow<Color, SizeLength, ShapeLength> { > /// Color. > pub color: Color, > /// Horizontal radius. > pub horizontal: SizeLength, > /// Vertical radius. > pub vertical: SizeLength, > /// Blur radius. >diff --git a/servo/components/style/values/generics/flex.rs b/servo/components/style/values/generics/flex.rs >index 1ab53233c446..9cbece2e1bc2 100644 >--- a/servo/components/style/values/generics/flex.rs >+++ b/servo/components/style/values/generics/flex.rs >@@ -1,17 +1,27 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS values related to flexbox. > > /// A generic value for the `flex-basis` property. > #[cfg_attr(feature = "servo", derive(MallocSizeOf))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, >- ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum FlexBasis<Width> { > /// `content` > Content, > /// `<width>` > Width(Width), > } >diff --git a/servo/components/style/values/generics/font.rs b/servo/components/style/values/generics/font.rs >index 02df291065f3..03a76c5a32d2 100644 >--- a/servo/components/style/values/generics/font.rs >+++ b/servo/components/style/values/generics/font.rs >@@ -11,18 +11,17 @@ use num_traits::One; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; > use std::io::Cursor; > use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; > use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; > > /// https://drafts.csswg.org/css-fonts-4/#feature-tag-value >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct FeatureTagValue<Integer> { > /// A four-character tag, packed into a u32 (one byte per character). > pub tag: FontTag, > /// The actual value. > pub value: Integer, > } > > impl<Integer> ToCss for FeatureTagValue<Integer> >@@ -42,18 +41,19 @@ where > > Ok(()) > } > } > > /// Variation setting for a single feature, see: > /// > /// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def >-#[derive(Animate, Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub struct VariationValue<Number> { > /// A four-character tag, packed into a u32 (one byte per character). > #[animation(constant)] > pub tag: FontTag, > /// The actual value. > pub value: Number, > } > >@@ -67,18 +67,17 @@ where > return Err(()); > } > self.value.compute_squared_distance(&other.value) > } > } > > /// A value both for font-variation-settings and font-feature-settings. > #[css(comma)] >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct FontSettings<T>(#[css(if_empty = "normal", iterable)] pub Box<[T]>); > > impl<T> FontSettings<T> { > /// Default value of font settings as `normal`. > #[inline] > pub fn normal() -> Self { > FontSettings(vec![].into_boxed_slice()) > } >@@ -104,18 +103,17 @@ impl<T: Parse> Parse for FontSettings<T> { > } > > /// A font four-character tag, represented as a u32 for convenience. > /// > /// See: > /// https://drafts.csswg.org/css-fonts-4/#font-variation-settings-def > /// https://drafts.csswg.org/css-fonts-4/#descdef-font-face-font-feature-settings > /// >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct FontTag(pub u32); > > impl ToCss for FontTag { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > use byteorder::{BigEndian, ByteOrder}; >@@ -140,18 +138,28 @@ impl Parse for FontTag { > return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > > let mut raw = Cursor::new(tag.as_bytes()); > Ok(FontTag(raw.read_u32::<BigEndian>().unwrap())) > } > } > >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- ToAnimatedValue, ToAnimatedZero, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToCss, >+)] > /// Additional information for keyword-derived font sizes. > pub struct KeywordInfo<Length> { > /// The keyword used > pub kw: KeywordSize, > /// A factor to be multiplied by the computed size of the keyword > #[css(skip)] > pub factor: f32, > /// An additional Au offset to add to the kw*factor in the case of calcs >@@ -184,19 +192,30 @@ where > > impl<L> SpecifiedValueInfo for KeywordInfo<L> { > fn collect_completion_keywords(f: KeywordsCollectFn) { > <KeywordSize as SpecifiedValueInfo>::collect_completion_keywords(f); > } > } > > /// CSS font keywords >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- Parse, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToCss, >+)] > #[allow(missing_docs)] > pub enum KeywordSize { > #[css(keyword = "xx-small")] > XXSmall, > XSmall, > Small, > Medium, > Large, >@@ -223,18 +242,29 @@ impl Default for KeywordSize { > } > } > > /// A generic value for the `font-style` property. > /// > /// https://drafts.csswg.org/css-fonts-4/#font-style-prop > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, Hash, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ Hash, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+)] > pub enum FontStyle<Angle> { > #[animation(error)] > Normal, > #[animation(error)] > Italic, > #[value_info(starts_with_keyword)] > Oblique(Angle), > } >diff --git a/servo/components/style/values/generics/gecko.rs b/servo/components/style/values/generics/gecko.rs >index 72a8b71d073e..d56158750b6b 100644 >--- a/servo/components/style/values/generics/gecko.rs >+++ b/servo/components/style/values/generics/gecko.rs >@@ -2,18 +2,17 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for legacy Gecko-only properties that should probably be > //! unshipped at some point in the future. > > /// A generic value for scroll snap points. > #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] >-#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, >- ToCss)] >+#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum ScrollSnapPoint<LengthOrPercentage> { > /// `none` > None, > /// `repeat(<length-or-percentage>)` > #[css(function)] > Repeat(LengthOrPercentage), > } > >diff --git a/servo/components/style/values/generics/grid.rs b/servo/components/style/values/generics/grid.rs >index b9ec85ace226..6e7c3ead2e11 100644 >--- a/servo/components/style/values/generics/grid.rs >+++ b/servo/components/style/values/generics/grid.rs >@@ -2,29 +2,28 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for the handling of > //! [grids](https://drafts.csswg.org/css-grid/). > > use cssparser::Parser; > use parser::{Parse, ParserContext}; >-use std::{mem, usize}; > use std::fmt::{self, Write}; >+use std::{mem, usize}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; >-use values::{CSSFloat, CustomIdent}; > use values::computed::{Context, ToComputedValue}; > use values::specified; > use values::specified::grid::parse_line_names; >+use values::{CSSFloat, CustomIdent}; > > /// A `<grid-line>` type. > /// > /// <https://drafts.csswg.org/css-grid/#typedef-grid-row-start-grid-line> >-#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct GridLine<Integer> { > /// Flag to check whether it's a `span` keyword. > pub is_span: bool, > /// A custom identifier for named lines. > /// > /// <https://drafts.csswg.org/css-grid/#grid-placement-slot> > pub ident: Option<CustomIdent>, > /// Denotes the nth grid line from grid item's placement. >@@ -144,30 +143,39 @@ impl Parse for GridLine<specified::Integer> { > } > > Ok(grid_line) > } > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum TrackKeyword { > Auto, > MaxContent, > MinContent, > } > > /// A track breadth for explicit grid track sizing. It's generic solely to > /// avoid re-implementing it for the computed type. > /// > /// <https://drafts.csswg.org/css-grid/#typedef-track-breadth> >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum TrackBreadth<L> { > /// The generic type is almost always a non-negative `<length-percentage>` > Breadth(L), > /// A flex fraction specified in `fr` units. > #[css(dimension)] > Fr(CSSFloat), > /// One of the track-sizing keywords (`auto`, `min-content`, `max-content`) > Keyword(TrackKeyword), >@@ -222,17 +230,17 @@ impl<L> TrackSize<L> { > if breadth_1.is_fixed() { > return true; // the second value is always a <track-breadth> > } > > match *breadth_1 { > TrackBreadth::Fr(_) => false, // should be <inflexible-breadth> at this point > _ => breadth_2.is_fixed(), > } >- }, >+ } > TrackSize::FitContent(_) => false, > } > } > } > > impl<L> Default for TrackSize<L> { > fn default() -> Self { > TrackSize::Breadth(TrackBreadth::Keyword(TrackKeyword::Auto)) >@@ -262,22 +270,22 @@ impl<L: ToCss> ToCss for TrackSize<L> { > } > } > > dest.write_str("minmax(")?; > min.to_css(dest)?; > dest.write_str(", ")?; > max.to_css(dest)?; > dest.write_str(")") >- }, >+ } > TrackSize::FitContent(ref lop) => { > dest.write_str("fit-content(")?; > lop.to_css(dest)?; > dest.write_str(")") >- }, >+ } > } > } > } > > impl<L: ToComputedValue> ToComputedValue for TrackSize<L> { > type ComputedValue = TrackSize<L::ComputedValue>; > > #[inline] >@@ -288,38 +296,38 @@ impl<L: ToComputedValue> ToComputedValue for TrackSize<L> { > // https://drafts.csswg.org/css-grid/#valdef-grid-template-columns-flex > // FIXME(nox): This sounds false, the spec just says that <flex> > // implies `minmax(auto, <flex>)`, not that it should be changed > // into `minmax` at computed value time. > TrackSize::Minmax( > TrackBreadth::Keyword(TrackKeyword::Auto), > TrackBreadth::Fr(f.to_computed_value(context)), > ) >- }, >+ } > TrackSize::Breadth(ref b) => TrackSize::Breadth(b.to_computed_value(context)), > TrackSize::Minmax(ref b1, ref b2) => { > TrackSize::Minmax(b1.to_computed_value(context), b2.to_computed_value(context)) >- }, >+ } > TrackSize::FitContent(ref lop) => TrackSize::FitContent(lop.to_computed_value(context)), > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > match *computed { > TrackSize::Breadth(ref b) => { > TrackSize::Breadth(ToComputedValue::from_computed_value(b)) >- }, >+ } > TrackSize::Minmax(ref b1, ref b2) => TrackSize::Minmax( > ToComputedValue::from_computed_value(b1), > ToComputedValue::from_computed_value(b2), > ), > TrackSize::FitContent(ref lop) => { > TrackSize::FitContent(ToComputedValue::from_computed_value(lop)) >- }, >+ } > } > } > } > > /// Helper function for serializing identifiers with a prefix and suffix, used > /// for serializing <line-names> (in grid). > pub fn concat_serialize_idents<W>( > prefix: &str, >@@ -378,18 +386,17 @@ impl Parse for RepeatCount<specified::Integer> { > } > } > } > > /// The structure containing `<line-names>` and `<track-size>` values. > /// > /// It can also hold `repeat()` function parameters, which expands into the respective > /// values in its computed form. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > #[css(function = "repeat")] > pub struct TrackRepeat<L, I> { > /// The number of times for the value to be repeated (could also be `auto-fit` or `auto-fill`) > pub count: RepeatCount<I>, > /// `<line-names>` accompanying `<track_size>` values. > /// > /// If there's no `<line-names>`, then it's represented by an empty vector. > /// For N `<track-size>` values, there will be N+1 `<line-names>`, and so this vector's >@@ -404,17 +411,18 @@ impl<L: ToCss, I: ToCss> ToCss for TrackRepeat<L, I> { > where > W: Write, > { > dest.write_str("repeat(")?; > self.count.to_css(dest)?; > dest.write_str(", ")?; > > let mut line_names_iter = self.line_names.iter(); >- for (i, (ref size, ref names)) in self.track_sizes >+ for (i, (ref size, ref names)) in self >+ .track_sizes > .iter() > .zip(&mut line_names_iter) > .enumerate() > { > if i > 0 { > dest.write_str(" ")?; > } > >@@ -466,18 +474,17 @@ impl<L: Clone> TrackRepeat<L, specified::Integer> { > track_sizes: self.track_sizes.clone(), > line_names: self.line_names.clone(), > } > } > } > } > > /// Track list values. Can be <track-size> or <track-repeat> >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum TrackListValue<LengthOrPercentage, Integer> { > /// A <track-size> value. > TrackSize(TrackSize<LengthOrPercentage>), > /// A <track-repeat> value. > TrackRepeat(TrackRepeat<LengthOrPercentage, Integer>), > } > > /// The type of a `<track-list>` as determined during parsing. >@@ -544,47 +551,46 @@ impl<L: ToCss, I: ToCss> ToCss for TrackList<L, I> { > > match self.auto_repeat { > Some(ref repeat) if idx == auto_idx => { > if !names.is_empty() { > dest.write_str(" ")?; > } > > repeat.to_css(dest)?; >- }, >+ } > _ => match values_iter.next() { > Some(value) => { > if !names.is_empty() { > dest.write_str(" ")?; > } > > value.to_css(dest)?; >- }, >+ } > None => break, > }, > } > >- if values_iter.peek().is_some() || >- line_names_iter.peek().map_or(false, |v| !v.is_empty()) || >- (idx + 1 == auto_idx) >+ if values_iter.peek().is_some() >+ || line_names_iter.peek().map_or(false, |v| !v.is_empty()) >+ || (idx + 1 == auto_idx) > { > dest.write_str(" ")?; > } > } > > Ok(()) > } > } > > /// The `<line-name-list>` for subgrids. > /// > /// `subgrid [ <line-names> | repeat(<positive-integer> | auto-fill, <line-names>+) ]+` > /// Old spec: https://www.w3.org/TR/2015/WD-css-grid-1-20150917/#typedef-line-name-list >-#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Default, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct LineNameList { > /// The optional `<line-name-list>` > pub names: Box<[Box<[CustomIdent]>]>, > /// Indicates the line name that requires `auto-fill` > pub fill_idx: Option<u32>, > } > > impl Parse for LineNameList { >@@ -619,23 +625,25 @@ impl Parse for LineNameList { > .iter() > .cloned() > .cycle() > .take(num.value() as usize * names_list.len()), > ), > RepeatCount::AutoFill if fill_idx.is_none() => { > // `repeat(autof-fill, ..)` should have just one line name. > if names_list.len() != 1 { >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::UnspecifiedError) >+ ); > } > let names = names_list.pop().unwrap(); > > line_names.push(names); > fill_idx = Some(line_names.len() as u32 - 1); >- }, >+ } > _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), > } > } else if let Ok(names) = input.try(parse_line_names) { > line_names.push(names); > } else { > break; > } > } >@@ -677,18 +685,17 @@ impl ToCss for LineNameList { > > Ok(()) > } > } > > /// Variants for `<grid-template-rows> | <grid-template-columns>` > /// Subgrid deferred to Level 2 spec due to lack of implementation. > /// But it's implemented in gecko, so we have to as well. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum GridTemplateComponent<L, I> { > /// `none` value. > None, > /// The grid `<track-list>` > TrackList(#[compute(field_bound)] TrackList<L, I>), > /// A `subgrid <line-name-list>?` > Subgrid(LineNameList), > } >diff --git a/servo/components/style/values/generics/image.rs b/servo/components/style/values/generics/image.rs >index 2da4d2900398..ccf732f9d517 100644 >--- a/servo/components/style/values/generics/image.rs >+++ b/servo/components/style/values/generics/image.rs >@@ -1,22 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for the handling of [images]. > //! > //! [images]: https://drafts.csswg.org/css-images/#image-values > >-use Atom; > use custom_properties; > use servo_arc::Arc; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ToCss}; > use values::serialize_atom_identifier; >+use Atom; > > /// An [image]. > /// > /// [image]: https://drafts.csswg.org/css-images/#image-values > #[derive(Clone, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub enum Image<Gradient, MozImageRect, ImageUrl> { > /// A `<url()>` image. > Url(ImageUrl), >@@ -140,17 +140,17 @@ pub struct PaintWorklet { > /// The name the worklet was registered with. > pub name: Atom, > /// The arguments for the worklet. > /// TODO: store a parsed representation of the arguments. > #[cfg_attr(feature = "servo", ignore_malloc_size_of = "Arc")] > pub arguments: Vec<Arc<custom_properties::SpecifiedValue>>, > } > >-impl ::style_traits::SpecifiedValueInfo for PaintWorklet { } >+impl ::style_traits::SpecifiedValueInfo for PaintWorklet {} > > impl ToCss for PaintWorklet { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > dest.write_str("paint(")?; > serialize_atom_identifier(&self.name, dest)?; >@@ -162,18 +162,17 @@ impl ToCss for PaintWorklet { > } > } > > /// Values for `moz-image-rect`. > /// > /// `-moz-image-rect(<uri>, top, right, bottom, left);` > #[allow(missing_docs)] > #[css(comma, function)] >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct MozImageRect<NumberOrPercentage, MozImageRectUrl> { > pub url: MozImageRectUrl, > pub top: NumberOrPercentage, > pub right: NumberOrPercentage, > pub bottom: NumberOrPercentage, > pub left: NumberOrPercentage, > } > >@@ -203,17 +202,17 @@ where > Image::Gradient(ref gradient) => gradient.to_css(dest), > Image::Rect(ref rect) => rect.to_css(dest), > #[cfg(feature = "servo")] > Image::PaintWorklet(ref paint_worklet) => paint_worklet.to_css(dest), > Image::Element(ref selector) => { > dest.write_str("-moz-element(#")?; > serialize_atom_identifier(selector, dest)?; > dest.write_str(")") >- }, >+ } > } > } > } > > impl<D, L, LoP, P, C, A> ToCss for Gradient<D, L, LoP, P, C, A> > where > D: LineDirection, > L: ToCss, >@@ -224,36 +223,36 @@ where > { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > match self.compat_mode { > CompatMode::WebKit => dest.write_str("-webkit-")?, > CompatMode::Moz => dest.write_str("-moz-")?, >- _ => {}, >+ _ => {} > } > > if self.repeating { > dest.write_str("repeating-")?; > } > dest.write_str(self.kind.label())?; > dest.write_str("-gradient(")?; > let mut skip_comma = match self.kind { > GradientKind::Linear(ref direction) if direction.points_downwards(self.compat_mode) => { > true >- }, >+ } > GradientKind::Linear(ref direction) => { > direction.to_css(dest, self.compat_mode)?; > false >- }, >+ } > GradientKind::Radial(ref shape, ref position, ref angle) => { > let omit_shape = match *shape { >- EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::Cover)) | >- EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true, >+ EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::Cover)) >+ | EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) => true, > _ => false, > }; > if self.compat_mode == CompatMode::Modern { > if !omit_shape { > shape.to_css(dest)?; > dest.write_str(" ")?; > } > dest.write_str("at ")?; >@@ -265,17 +264,17 @@ where > a.to_css(dest)?; > } > if !omit_shape { > dest.write_str(", ")?; > shape.to_css(dest)?; > } > } > false >- }, >+ } > }; > for item in &self.items { > if !skip_comma { > dest.write_str(", ")?; > } > skip_comma = false; > item.to_css(dest)?; > } >@@ -309,17 +308,17 @@ where > { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > match *self { > Circle::Extent(ShapeExtent::FarthestCorner) | Circle::Extent(ShapeExtent::Cover) => { > dest.write_str("circle") >- }, >+ } > Circle::Extent(keyword) => { > dest.write_str("circle ")?; > keyword.to_css(dest) >- }, >+ } > Circle::Radius(ref length) => length.to_css(dest), > } > } > } >diff --git a/servo/components/style/values/generics/mod.rs b/servo/components/style/values/generics/mod.rs >index e6c1befea9f8..056c0e529c4b 100644 >--- a/servo/components/style/values/generics/mod.rs >+++ b/servo/components/style/values/generics/mod.rs >@@ -1,21 +1,21 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types that share their serialization implementations > //! for both specified and computed values. > >+use super::CustomIdent; > use counter_style::{parse_counter_style_name, Symbols}; > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use style_traits::{KeywordsCollectFn, ParseError}; > use style_traits::{SpecifiedValueInfo, StyleParseErrorKind}; >-use super::CustomIdent; > > pub mod background; > pub mod basic_shape; > pub mod border; > #[path = "box.rs"] > pub mod box_; > pub mod color; > pub mod column; >@@ -118,18 +118,18 @@ impl Parse for CounterStyleOrNone { > if input.try(|i| i.expect_function_matching("symbols")).is_ok() { > return input.parse_nested_block(|input| { > let symbols_type = input > .try(|i| SymbolsType::parse(i)) > .unwrap_or(SymbolsType::Symbolic); > let symbols = Symbols::parse(context, input)?; > // There must be at least two symbols for alphabetic or > // numeric system. >- if (symbols_type == SymbolsType::Alphabetic || >- symbols_type == SymbolsType::Numeric) && symbols.0.len() < 2 >+ if (symbols_type == SymbolsType::Alphabetic || symbols_type == SymbolsType::Numeric) >+ && symbols.0.len() < 2 > { > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > // Identifier is not allowed in symbols() function. > if symbols.0.iter().any(|sym| !sym.is_allowed_in_symbols()) { > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > Ok(CounterStyleOrNone::Symbols(symbols_type, symbols)) >@@ -152,19 +152,42 @@ impl SpecifiedValueInfo for CounterStyleOrNone { > } > } > include!("../../counter_style/predefined.rs"); > } > } > > /// A wrapper of Non-negative values. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, Hash, MallocSizeOf, >- PartialEq, PartialOrd, SpecifiedValueInfo, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ Hash, >+ MallocSizeOf, >+ PartialEq, >+ PartialOrd, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub struct NonNegative<T>(pub T); > > /// A wrapper of greater-than-or-equal-to-one values. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, PartialOrd, SpecifiedValueInfo, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ PartialOrd, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub struct GreaterThanOrEqualToOne<T>(pub T); >diff --git a/servo/components/style/values/generics/position.rs b/servo/components/style/values/generics/position.rs >index 67c167c41ab6..83dc48d0905e 100644 >--- a/servo/components/style/values/generics/position.rs >+++ b/servo/components/style/values/generics/position.rs >@@ -1,18 +1,28 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS handling of specified and computed values of > //! [`position`](https://drafts.csswg.org/css-backgrounds-3/#position) > > /// A generic type for representing a CSS [position](https://drafts.csswg.org/css-values/#position). >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+)] > pub struct Position<H, V> { > /// The horizontal component of position. > pub horizontal: H, > /// The vertical component of position. > pub vertical: V, > } > > impl<H, V> Position<H, V> { >@@ -21,18 +31,29 @@ impl<H, V> Position<H, V> { > Self { > horizontal: horizontal, > vertical: vertical, > } > } > } > > /// A generic value for the `z-index` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum ZIndex<Integer> { > /// An integer value. > Integer(Integer), > /// The keyword `auto`. > Auto, > } > > impl<Integer> ZIndex<Integer> { >diff --git a/servo/components/style/values/generics/rect.rs b/servo/components/style/values/generics/rect.rs >index fb67e48a3954..510cb75a6f8b 100644 >--- a/servo/components/style/values/generics/rect.rs >+++ b/servo/components/style/values/generics/rect.rs >@@ -6,18 +6,27 @@ > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, ToCss}; > > /// A CSS value made of four components, where its `ToCss` impl will try to > /// serialize as few components as possible, like for example in `border-width`. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+)] > pub struct Rect<T>(pub T, pub T, pub T, pub T); > > impl<T> Rect<T> { > /// Returns a new `Rect<T>` value. > pub fn new(first: T, second: T, third: T, fourth: T) -> Self { > Rect(first, second, third, fourth) > } > } >diff --git a/servo/components/style/values/generics/size.rs b/servo/components/style/values/generics/size.rs >index ad93b94e65ee..d7ef5810f05b 100644 >--- a/servo/components/style/values/generics/size.rs >+++ b/servo/components/style/values/generics/size.rs >@@ -8,18 +8,27 @@ use cssparser::Parser; > use euclid::Size2D; > use parser::ParserContext; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss}; > use values::animated::ToAnimatedValue; > > /// A generic size, for `border-*-radius` longhand properties, or > /// `border-spacing`. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- ToAnimatedZero, ToComputedValue)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ ToAnimatedZero, >+ ToComputedValue, >+)] > pub struct Size<L>(pub Size2D<L>); > > impl<L> Size<L> { > #[inline] > /// Create a new `Size` for an area of given width and height. > pub fn new(width: L, height: L) -> Size<L> { > Size(Size2D::new(width, height)) > } >diff --git a/servo/components/style/values/generics/svg.rs b/servo/components/style/values/generics/svg.rs >index 0fbaacf22833..a923f99dcfa4 100644 >--- a/servo/components/style/values/generics/svg.rs >+++ b/servo/components/style/values/generics/svg.rs >@@ -2,43 +2,63 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS values in SVG > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use style_traits::{ParseError, StyleParseErrorKind}; >-use values::{Either, None_}; >-use values::computed::NumberOrPercentage; > use values::computed::length::LengthOrPercentage; >+use values::computed::NumberOrPercentage; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; >+use values::{Either, None_}; > > /// An SVG paint value > /// > /// <https://www.w3.org/TR/SVG2/painting.html#SpecifyingPaint> > #[animation(no_bound(UrlPaintServer))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToComputedValue, >+ ToCss, >+)] > pub struct SVGPaint<ColorType, UrlPaintServer> { > /// The paint source > pub kind: SVGPaintKind<ColorType, UrlPaintServer>, > /// The fallback color. It would be empty, the `none` keyword or <color>. > pub fallback: Option<Either<ColorType, None_>>, > } > > /// An SVG paint value without the fallback > /// > /// Whereas the spec only allows PaintServer > /// to have a fallback, Gecko lets the context > /// properties have a fallback as well. > #[animation(no_bound(UrlPaintServer))] >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, >- ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum SVGPaintKind<ColorType, UrlPaintServer> { > /// `none` > #[animation(error)] > None, > /// `<color>` > Color(ColorType), > /// `url(...)` > #[animation(error)] >@@ -108,18 +128,28 @@ impl<ColorType: Parse, UrlPaintServer: Parse> Parse for SVGPaint<ColorType, UrlP > } else { > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > } > > /// A value of <length> | <percentage> | <number> for svg which allow unitless length. > /// <https://www.w3.org/TR/SVG11/painting.html#StrokeProperties> >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToAnimatedValue, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum SvgLengthOrPercentageOrNumber<LengthOrPercentage, Number> { > /// <length> | <percentage> > LengthOrPercentage(LengthOrPercentage), > /// <number> > Number(Number), > } > > impl<L, N> ComputeSquaredDistance for SvgLengthOrPercentageOrNumber<L, N> >@@ -159,17 +189,17 @@ where > /// return true if this struct has calc value. > pub fn has_calc(&self) -> bool { > match self { > &SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop) => { > match LengthOrPercentage::from(lop) { > LengthOrPercentage::Calc(_) => true, > _ => false, > } >- }, >+ } > _ => false, > } > } > } > > /// Parsing the SvgLengthOrPercentageOrNumber. At first, we need to parse number > /// since prevent converting to the length. > impl<LengthOrPercentageType: Parse, NumberType: Parse> Parse >@@ -186,44 +216,69 @@ impl<LengthOrPercentageType: Parse, NumberType: Parse> Parse > if let Ok(lop) = input.try(|i| LengthOrPercentageType::parse(context, i)) { > return Ok(SvgLengthOrPercentageOrNumber::LengthOrPercentage(lop)); > } > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > > /// An SVG length value supports `context-value` in addition to length. >-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, >- ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum SVGLength<LengthType> { > /// `<length> | <percentage> | <number>` > Length(LengthType), > /// `context-value` > ContextValue, > } > > /// Generic value for stroke-dasharray. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToComputedValue, >+ ToCss, >+)] > pub enum SVGStrokeDashArray<LengthType> { > /// `[ <length> | <percentage> | <number> ]#` > #[css(comma)] >- Values( >- #[css(if_empty = "none", iterable)] >- Vec<LengthType>, >- ), >+ Values(#[css(if_empty = "none", iterable)] Vec<LengthType>), > /// `context-value` > ContextValue, > } > > /// An SVG opacity value accepts `context-{fill,stroke}-opacity` in > /// addition to opacity value. >-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum SVGOpacity<OpacityType> { > /// `<opacity-value>` > Opacity(OpacityType), > /// `context-fill-opacity` > ContextFillOpacity, > /// `context-stroke-opacity` > ContextStrokeOpacity, > } >diff --git a/servo/components/style/values/generics/text.rs b/servo/components/style/values/generics/text.rs >index 6cc5caaac777..e85c444a6956 100644 >--- a/servo/components/style/values/generics/text.rs >+++ b/servo/components/style/values/generics/text.rs >@@ -7,36 +7,38 @@ > use app_units::Au; > use cssparser::Parser; > use parser::ParserContext; > use style_traits::ParseError; > use values::animated::{Animate, Procedure, ToAnimatedZero}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; > > /// A generic value for the `initial-letter` property. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum InitialLetter<Number, Integer> { > /// `normal` > Normal, > /// `<number> <integer>?` > Specified(Number, Option<Integer>), > } > > impl<N, I> InitialLetter<N, I> { > /// Returns `normal`. > #[inline] > pub fn normal() -> Self { > InitialLetter::Normal > } > } > > /// A generic spacing value for the `letter-spacing` and `word-spacing` properties. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum Spacing<Value> { > /// `normal` > Normal, > /// `<value>` > Value(Value), > } > > impl<Value> Spacing<Value> { >@@ -107,18 +109,28 @@ where > { > #[inline] > fn to_animated_zero(&self) -> Result<Self, ()> { > Err(()) > } > } > > /// A generic value for the `line-height` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToCss, >+)] > pub enum LineHeight<Number, LengthOrPercentage> { > /// `normal` > Normal, > /// `-moz-block-height` > #[cfg(feature = "gecko")] > MozBlockHeight, > /// `<number>` > Number(Number), >@@ -137,17 +149,28 @@ impl<N, L> LineHeight<N, L> { > /// Returns `normal`. > #[inline] > pub fn normal() -> Self { > LineHeight::Normal > } > } > > /// A generic value for the `-moz-tab-size` property. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, >- ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum MozTabSize<Number, Length> { > /// A number. > Number(Number), > /// A length. > Length(Length), > } >diff --git a/servo/components/style/values/generics/transform.rs b/servo/components/style/values/generics/transform.rs >index a0cbc57d6b43..fc81617bfc73 100644 >--- a/servo/components/style/values/generics/transform.rs >+++ b/servo/components/style/values/generics/transform.rs >@@ -2,26 +2,27 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic types for CSS values that are related to transformations. > > use app_units::Au; > use euclid::{self, Rect, Transform3D}; > use num_traits::Zero; >-use values::{computed, CSSFloat}; > use values::computed::length::Length as ComputedLength; > use values::computed::length::LengthOrPercentage as ComputedLengthOrPercentage; > use values::specified::length::Length as SpecifiedLength; > use values::specified::length::LengthOrPercentage as SpecifiedLengthOrPercentage; >+use values::{computed, CSSFloat}; > > /// A generic 2D transformation matrix. > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > #[css(comma, function)] > pub struct Matrix<T> { > pub a: T, > pub b: T, > pub c: T, > pub d: T, > pub e: T, > pub f: T, >@@ -61,32 +62,42 @@ impl<T: Into<f64>> From<Matrix3D<T>> for Transform3D<f64> { > m.m21.into(), m.m22.into(), m.m23.into(), m.m24.into(), > m.m31.into(), m.m32.into(), m.m33.into(), m.m34.into(), > m.m41.into(), m.m42.into(), m.m43.into(), m.m44.into(), > ) > } > } > > /// A generic transform origin. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, >- PartialEq, SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub struct TransformOrigin<H, V, Depth> { > /// The horizontal origin. > pub horizontal: H, > /// The vertical origin. > pub vertical: V, > /// The depth. > pub depth: Depth, > } > > /// A generic timing function. > /// > /// <https://drafts.csswg.org/css-timing-1/#single-timing-function-production> >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > #[value_info(ty = "TIMING_FUNCTION")] > pub enum TimingFunction<Integer, Number> { > /// `linear | ease | ease-in | ease-out | ease-in-out` > Keyword(TimingKeyword), > /// `cubic-bezier(<number>, <number>, <number>, <number>)` > #[allow(missing_docs)] > #[css(comma, function)] > CubicBezier { >@@ -101,18 +112,28 @@ pub enum TimingFunction<Integer, Number> { > Steps(Integer, #[css(skip_if = "is_end")] StepPosition), > /// `frames(<integer>)` > #[css(comma, function)] > Frames(Integer), > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum TimingKeyword { > Linear, > Ease, > EaseIn, > EaseOut, > EaseInOut, > } > >@@ -158,18 +179,17 @@ impl TimingKeyword { > TimingKeyword::Ease => (0.25, 0.1, 0.25, 1.), > TimingKeyword::EaseIn => (0.42, 0., 1., 1.), > TimingKeyword::EaseOut => (0., 0., 0.58, 1.), > TimingKeyword::EaseInOut => (0.42, 0., 0.58, 1.), > } > } > } > >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > /// A single operation in the list of a `transform` value > pub enum TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage> { > /// Represents a 2D 2x3 matrix. > Matrix(Matrix<Number>), > /// Represents a 3D 4x4 matrix. > Matrix3D(Matrix3D<Number>), > /// A 2D skew. > /// >@@ -263,44 +283,39 @@ pub enum TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage> > AccumulateMatrix { > from_list: > Transform<TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage>>, > to_list: Transform<TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage>>, > count: Integer, > }, > } > >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > /// A value of the `transform` property > pub struct Transform<T>(#[css(if_empty = "none", iterable)] pub Vec<T>); > > impl<Angle, Number, Length, Integer, LengthOrPercentage> > TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage> > { > /// Check if it is any rotate function. > pub fn is_rotate(&self) -> bool { > use self::TransformOperation::*; > matches!( > *self, >- Rotate(..) | >- Rotate3D(..) | >- RotateX(..) | >- RotateY(..) | >- RotateZ(..) >+ Rotate(..) | Rotate3D(..) | RotateX(..) | RotateY(..) | RotateZ(..) > ) > } > > /// Check if it is any translate function > pub fn is_translate(&self) -> bool { > use self::TransformOperation::*; > match *self { > Translate(..) | Translate3D(..) | TranslateX(..) | TranslateY(..) | TranslateZ(..) => { > true >- }, >+ } > _ => false, > } > } > > /// Check if it is any scale function > pub fn is_scale(&self) -> bool { > use self::TransformOperation::*; > match *self { >@@ -386,18 +401,18 @@ where > Number: Copy + Into<f32> + Into<f64>, > Length: ToAbsoluteLength, > LoP: ToAbsoluteLength, > { > #[inline] > fn is_3d(&self) -> bool { > use self::TransformOperation::*; > match *self { >- Translate3D(..) | TranslateZ(..) | Rotate3D(..) | RotateX(..) | RotateY(..) | >- RotateZ(..) | Scale3D(..) | ScaleZ(..) | Perspective(..) | Matrix3D(..) => true, >+ Translate3D(..) | TranslateZ(..) | Rotate3D(..) | RotateX(..) | RotateY(..) >+ | RotateZ(..) | Scale3D(..) | ScaleZ(..) | Perspective(..) | Matrix3D(..) => true, > _ => false, > } > } > > /// If |reference_box| is None, we will drop the percent part from translate because > /// we cannot resolve it without the layout info, for computed TransformOperation. > /// However, for specified TransformOperation, we will return Err(()) if there is any relative > /// lengths because the only caller, DOMMatrix, doesn't accept relative lengths. >@@ -415,59 +430,59 @@ where > let (ax, ay, az, theta) = > get_normalized_vector_and_angle(ax.into(), ay.into(), az.into(), theta); > Transform3D::create_rotation( > ax as f64, > ay as f64, > az as f64, > euclid::Angle::radians(theta), > ) >- }, >+ } > RotateX(theta) => { > let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64()); > Transform3D::create_rotation(1., 0., 0., theta) >- }, >+ } > RotateY(theta) => { > let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64()); > Transform3D::create_rotation(0., 1., 0., theta) >- }, >+ } > RotateZ(theta) | Rotate(theta) => { > let theta = euclid::Angle::radians(TWO_PI - theta.as_ref().radians64()); > Transform3D::create_rotation(0., 0., 1., theta) >- }, >+ } > Perspective(ref d) => { > let m = create_perspective_matrix(d.to_pixel_length(None)?); > m.cast() >- }, >+ } > Scale3D(sx, sy, sz) => Transform3D::create_scale(sx.into(), sy.into(), sz.into()), > Scale(sx, sy) => Transform3D::create_scale(sx.into(), sy.unwrap_or(sx).into(), 1.), > ScaleX(s) => Transform3D::create_scale(s.into(), 1., 1.), > ScaleY(s) => Transform3D::create_scale(1., s.into(), 1.), > ScaleZ(s) => Transform3D::create_scale(1., 1., s.into()), > Translate3D(ref tx, ref ty, ref tz) => { > let tx = tx.to_pixel_length(reference_width)? as f64; > let ty = ty.to_pixel_length(reference_height)? as f64; > Transform3D::create_translation(tx, ty, tz.to_pixel_length(None)? as f64) >- }, >+ } > Translate(ref tx, Some(ref ty)) => { > let tx = tx.to_pixel_length(reference_width)? as f64; > let ty = ty.to_pixel_length(reference_height)? as f64; > Transform3D::create_translation(tx, ty, 0.) >- }, >+ } > TranslateX(ref t) | Translate(ref t, None) => { > let t = t.to_pixel_length(reference_width)? as f64; > Transform3D::create_translation(t, 0., 0.) >- }, >+ } > TranslateY(ref t) => { > let t = t.to_pixel_length(reference_height)? as f64; > Transform3D::create_translation(0., t, 0.) >- }, >+ } > TranslateZ(ref z) => { > Transform3D::create_translation(0., 0., z.to_pixel_length(None)? as f64) >- }, >+ } > Skew(theta_x, theta_y) => Transform3D::create_skew( > euclid::Angle::radians(theta_x.as_ref().radians64()), > euclid::Angle::radians(theta_y.map_or(0., |a| a.as_ref().radians64())), > ), > SkewX(theta) => Transform3D::create_skew( > euclid::Angle::radians(theta.as_ref().radians64()), > euclid::Angle::radians(0.), > ), >@@ -480,17 +495,17 @@ where > InterpolateMatrix { .. } | AccumulateMatrix { .. } => { > // TODO: Convert InterpolateMatrix/AccumulateMatrix into a valid Transform3D by > // the reference box and do interpolation on these two Transform3D matrices. > // Both Gecko and Servo don't support this for computing distance, and Servo > // doesn't support animations on InterpolateMatrix/AccumulateMatrix, so > // return an identity matrix. > // Note: DOMMatrix doesn't go into this arm. > Transform3D::identity() >- }, >+ } > }; > Ok(matrix) > } > } > > impl<T> Transform<T> { > /// `none` > pub fn none() -> Self { >@@ -569,64 +584,94 @@ pub fn get_normalized_vector_and_angle<T: Zero>( > // rotation to not be applied, so we use identity matrix (i.e. rotate3d(0, 0, 1, 0)). > (0., 0., 1., T::zero()) > } else { > let vector = vector.robust_normalize(); > (vector.x, vector.y, vector.z, angle) > } > } > >-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > /// A value of the `Rotate` property > /// > /// <https://drafts.csswg.org/css-transforms-2/#individual-transforms> > pub enum Rotate<Number, Angle> { > /// 'none' > None, > /// '<angle>' > Rotate(Angle), > /// '<number>{3} <angle>' > Rotate3D(Number, Number, Number, Angle), > } > >-#[derive(Clone, ComputeSquaredDistance, Copy, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > /// A value of the `Scale` property > /// > /// <https://drafts.csswg.org/css-transforms-2/#individual-transforms> > pub enum Scale<Number> { > /// 'none' > None, > /// '<number>' > ScaleX(Number), > /// '<number>{2}' > Scale(Number, Number), > /// '<number>{3}' > Scale3D(Number, Number, Number), > } > >-#[derive(Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedZero, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > /// A value of the `Translate` property > /// > /// <https://drafts.csswg.org/css-transforms-2/#individual-transforms> > pub enum Translate<LengthOrPercentage, Length> { > /// 'none' > None, > /// '<length-percentage>' > TranslateX(LengthOrPercentage), > /// '<length-percentage> <length-percentage>' > Translate(LengthOrPercentage, LengthOrPercentage), > /// '<length-percentage> <length-percentage> <length>' > Translate3D(LengthOrPercentage, LengthOrPercentage, Length), > } > > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub enum TransformStyle { > #[cfg(feature = "servo")] > Auto, > Flat, > #[css(keyword = "preserve-3d")] > Preserve3d, > } >diff --git a/servo/components/style/values/generics/ui.rs b/servo/components/style/values/generics/ui.rs >index 9ccf1f80d537..68841c82778c 100644 >--- a/servo/components/style/values/generics/ui.rs >+++ b/servo/components/style/values/generics/ui.rs >@@ -1,23 +1,22 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Generic values for UI properties. > > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ToCss}; > use style_traits::cursor::CursorKind; >+use style_traits::{CssWriter, ToCss}; > > /// A generic value for the `cursor` property. > /// > /// https://drafts.csswg.org/css-ui/#cursor >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct Cursor<Image> { > /// The parsed images for the cursor. > pub images: Box<[Image]>, > /// The kind of the cursor [default | help | ...]. > pub keyword: CursorKind, > } > > impl<Image> Cursor<Image> { >@@ -40,18 +39,17 @@ impl<Image: ToCss> ToCss for Cursor<Image> { > image.to_css(dest)?; > dest.write_str(", ")?; > } > self.keyword.to_css(dest) > } > } > > /// A generic value for item of `image cursors`. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct CursorImage<ImageUrl, Number> { > /// The url to parse images from. > pub url: ImageUrl, > /// The <x> and <y> coordinates. > pub hotspot: Option<(Number, Number)>, > } > > impl<ImageUrl: ToCss, Number: ToCss> ToCss for CursorImage<ImageUrl, Number> { >diff --git a/servo/components/style/values/generics/url.rs b/servo/components/style/values/generics/url.rs >index 5da74a7b0874..ff9fa16d6655 100644 >--- a/servo/components/style/values/generics/url.rs >+++ b/servo/components/style/values/generics/url.rs >@@ -4,19 +4,29 @@ > > //! Generic types for url properties. > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use style_traits::ParseError; > > /// An image url or none, used for example in list-style-image >-#[derive(Animate, Clone, ComputeSquaredDistance, Debug, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, >- ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Debug, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum UrlOrNone<Url> { > /// `none` > None, > /// `A URL` > Url(Url), > } > > impl<Url> UrlOrNone<Url> { >diff --git a/servo/components/style/values/mod.rs b/servo/components/style/values/mod.rs >index a5f8d0abd32e..f182477e374a 100644 >--- a/servo/components/style/values/mod.rs >+++ b/servo/components/style/values/mod.rs >@@ -3,29 +3,31 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Common [values][values] used in CSS. > //! > //! [values]: https://drafts.csswg.org/css-values/ > > #![deny(missing_docs)] > >-use Atom; >-pub use cssparser::{serialize_identifier, serialize_name, CowRcStr, Parser, SourceLocation, Token, RGBA}; >+pub use cssparser::{ >+ serialize_identifier, serialize_name, CowRcStr, Parser, SourceLocation, Token, RGBA, >+}; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use std::fmt::{self, Debug, Write}; > use std::hash; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use values::distance::{ComputeSquaredDistance, SquaredDistance}; >+use Atom; > >-#[cfg(feature = "servo")] >-pub use servo::url::CssUrl; > #[cfg(feature = "gecko")] > pub use gecko::url::CssUrl; >+#[cfg(feature = "servo")] >+pub use servo::url::CssUrl; > > pub mod animated; > pub mod computed; > pub mod distance; > pub mod generics; > pub mod specified; > > /// A CSS float value. >@@ -87,18 +89,23 @@ pub fn serialize_percentage<W>(value: CSSFloat, dest: &mut CssWriter<W>) -> fmt: > where > W: Write, > { > (value * 100.).to_css(dest)?; > dest.write_str("%") > } > > /// Convenience void type to disable some properties and values through types. >-#[cfg_attr(feature = "servo", derive(Deserialize, MallocSizeOf, Serialize))] >-#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss)] >+#[cfg_attr( >+ feature = "servo", >+ derive(Deserialize, MallocSizeOf, Serialize) >+)] >+#[derive( >+ Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToAnimatedValue, ToComputedValue, ToCss, >+)] > pub enum Impossible {} > > // FIXME(nox): This should be derived but the derive code cannot cope > // with uninhabited enums. > impl ComputeSquaredDistance for Impossible { > #[inline] > fn compute_squared_distance(&self, _other: &Self) -> Result<SquaredDistance, ()> { > match *self {} >@@ -110,19 +117,29 @@ impl Parse for Impossible { > _context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > > /// A struct representing one of two kinds of values. >-#[derive(Animate, Clone, ComputeSquaredDistance, Copy, MallocSizeOf, PartialEq, >- SpecifiedValueInfo, ToAnimatedValue, ToAnimatedZero, ToComputedValue, >- ToCss)] >+#[derive( >+ Animate, >+ Clone, >+ ComputeSquaredDistance, >+ Copy, >+ MallocSizeOf, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToAnimatedValue, >+ ToAnimatedZero, >+ ToComputedValue, >+ ToCss, >+)] > pub enum Either<A, B> { > /// The first value. > First(A), > /// The second kind of value. > Second(B), > } > > impl<A: Debug, B: Debug> Debug for Either<A, B> { >@@ -143,33 +160,34 @@ impl<A: Parse, B: Parse> Parse for Either<A, B> { > Ok(Either::First(v)) > } else { > B::parse(context, input).map(Either::Second) > } > } > } > > /// <https://drafts.csswg.org/css-values-4/#custom-idents> >-#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct CustomIdent(pub Atom); > > impl CustomIdent { > /// Parse an already-tokenizer identifier > pub fn from_ident<'i>( > location: SourceLocation, > ident: &CowRcStr<'i>, > excluding: &[&str], > ) -> Result<Self, ParseError<'i>> { > let valid = match_ignore_ascii_case! { ident, > "initial" | "inherit" | "unset" | "default" => false, > _ => true > }; > if !valid { >- return Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); >+ return Err( >+ location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) >+ ); > } > if excluding.iter().any(|s| ident.eq_ignore_ascii_case(s)) { > Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } else { > Ok(CustomIdent(Atom::from(ident.as_ref()))) > } > } > } >diff --git a/servo/components/style/values/specified/align.rs b/servo/components/style/values/specified/align.rs >index 731844bcb52c..780ab60edb76 100644 >--- a/servo/components/style/values/specified/align.rs >+++ b/servo/components/style/values/specified/align.rs >@@ -85,23 +85,23 @@ impl ToCss for AlignFlags { > > match extra_flags { > AlignFlags::LEGACY => { > dest.write_str("legacy")?; > if value.is_empty() { > return Ok(()); > } > dest.write_char(' ')?; >- }, >+ } > AlignFlags::SAFE => dest.write_str("safe ")?, > // Don't serialize "unsafe", since it's the default. >- AlignFlags::UNSAFE => {}, >+ AlignFlags::UNSAFE => {} > _ => { > debug_assert_eq!(extra_flags, AlignFlags::empty()); >- }, >+ } > } > > dest.write_str(match value { > AlignFlags::AUTO => "auto", > AlignFlags::NORMAL => "normal", > AlignFlags::START => "start", > AlignFlags::END => "end", > AlignFlags::FLEX_START => "flex-start", >@@ -678,18 +678,23 @@ fn parse_self_position<'i, 't>( > "self-end" => AlignFlags::SELF_END, > "left" if axis == AxisDirection::Inline => AlignFlags::LEFT, > "right" if axis == AxisDirection::Inline => AlignFlags::RIGHT, > }) > } > > fn list_self_position_keywords(f: KeywordsCollectFn, axis: AxisDirection) { > f(&[ >- "start", "end", "flex-start", "flex-end", >- "center", "self-start", "self-end", >+ "start", >+ "end", >+ "flex-start", >+ "flex-end", >+ "center", >+ "self-start", >+ "self-end", > ]); > if axis == AxisDirection::Inline { > f(&["left", "right"]); > } > } > > fn parse_left_right_center<'i, 't>( > input: &mut Parser<'i, 't>, >diff --git a/servo/components/style/values/specified/angle.rs b/servo/components/style/values/specified/angle.rs >index 040ea9d9a7c8..e10f8cc5f142 100644 >--- a/servo/components/style/values/specified/angle.rs >+++ b/servo/components/style/values/specified/angle.rs >@@ -3,20 +3,20 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified angles. > > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss}; >-use values::CSSFloat; >-use values::computed::{Context, ToComputedValue}; > use values::computed::angle::Angle as ComputedAngle; >+use values::computed::{Context, ToComputedValue}; > use values::specified::calc::CalcNode; >+use values::CSSFloat; > > /// A specified angle. > /// > /// Computed angles are essentially same as specified ones except for `calc()` > /// value serialization. Therefore we are storing a computed angle inside > /// to hold the actual value and its unit. > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] >@@ -186,22 +186,22 @@ impl Angle { > ) -> Result<Self, ParseError<'i>> { > // FIXME: remove clone() when lifetimes are non-lexical > let token = input.next()?.clone(); > match token { > Token::Dimension { > value, ref unit, .. > } => { > Angle::parse_dimension(value, unit, /* from_calc = */ false) >- }, >+ } > Token::Number { value, .. } if value == 0. => match allow_unitless_zero { > AllowUnitlessZeroAngle::Yes => Ok(Angle::zero()), > AllowUnitlessZeroAngle::No => Err(()), > }, > Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => { > return input.parse_nested_block(|i| CalcNode::parse_angle(context, i)) >- }, >+ } > _ => Err(()), > }.map_err(|()| input.new_unexpected_token_error(token.clone())) > } > } > > impl SpecifiedValueInfo for Angle {} >diff --git a/servo/components/style/values/specified/background.rs b/servo/components/style/values/specified/background.rs >index d7c4ec629cad..93c39f81ebd1 100644 >--- a/servo/components/style/values/specified/background.rs >+++ b/servo/components/style/values/specified/background.rs >@@ -38,31 +38,40 @@ impl BackgroundSize { > GenericBackgroundSize::Explicit { > width: NonNegativeLengthOrPercentageOrAuto::auto(), > height: NonNegativeLengthOrPercentageOrAuto::auto(), > } > } > } > > /// One of the keywords for `background-repeat`. >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > #[allow(missing_docs)] > pub enum BackgroundRepeatKeyword { > Repeat, > Space, > Round, > NoRepeat, > } > > /// The specified value for the `background-repeat` property. > /// > /// https://drafts.csswg.org/css-backgrounds/#the-background-repeat >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum BackgroundRepeat { > /// `repeat-x` > RepeatX, > /// `repeat-y` > RepeatY, > /// `[repeat | space | round | no-repeat]{1,2}` > Keywords(BackgroundRepeatKeyword, Option<BackgroundRepeatKeyword>), > } >@@ -86,16 +95,18 @@ impl Parse for BackgroundRepeat { > "repeat-x" => return Ok(BackgroundRepeat::RepeatX), > "repeat-y" => return Ok(BackgroundRepeat::RepeatY), > _ => {}, > } > > let horizontal = match BackgroundRepeatKeyword::from_ident(&ident) { > Ok(h) => h, > Err(()) => { >- return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))); >- }, >+ return Err( >+ input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone())) >+ ); >+ } > }; > > let vertical = input.try(BackgroundRepeatKeyword::parse).ok(); > Ok(BackgroundRepeat::Keywords(horizontal, vertical)) > } > } >diff --git a/servo/components/style/values/specified/basic_shape.rs b/servo/components/style/values/specified/basic_shape.rs >index 23ae91d564e5..6c1872f37754 100644 >--- a/servo/components/style/values/specified/basic_shape.rs >+++ b/servo/components/style/values/specified/basic_shape.rs >@@ -11,22 +11,22 @@ use cssparser::Parser; > use parser::{Parse, ParserContext}; > use std::borrow::Cow; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use values::computed::Percentage; > use values::generics::basic_shape as generic; > use values::generics::basic_shape::{FillRule, GeometryBox, ShapeBox, ShapeSource}; > use values::generics::rect::Rect; >-use values::specified::LengthOrPercentage; > use values::specified::border::BorderRadius; > use values::specified::image::Image; > use values::specified::position::{HorizontalPosition, Position, PositionComponent}; > use values::specified::position::{Side, VerticalPosition}; > use values::specified::url::SpecifiedUrl; >+use values::specified::LengthOrPercentage; > > /// A specified clipping shape. > pub type ClippingShape = generic::ClippingShape<BasicShape, SpecifiedUrl>; > > /// A specified float area shape. > pub type FloatAreaShape = generic::FloatAreaShape<BasicShape, Image>; > > /// A specified basic shape. >@@ -75,18 +75,18 @@ where > > *component = input.try(|i| U::parse(context, i)).ok(); > component.is_some() > } > > let mut shape = None; > let mut ref_box = None; > >- while parse_component(context, input, &mut shape) || >- parse_component(context, input, &mut ref_box) >+ while parse_component(context, input, &mut shape) >+ || parse_component(context, input, &mut ref_box) > { > // > } > > if let Some(shp) = shape { > return Ok(ShapeSource::Shape(shp, ref_box)); > } > >@@ -224,18 +224,17 @@ impl Ellipse { > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let (a, b) = input > .try(|i| -> Result<_, ParseError> { > Ok(( > ShapeRadius::parse(context, i)?, > ShapeRadius::parse(context, i)?, > )) >- }) >- .unwrap_or_default(); >+ }).unwrap_or_default(); > let position = if input.try(|i| i.expect_ident_matching("at")).is_ok() { > Position::parse(context, input)? > } else { > Position::center() > }; > > Ok(generic::Ellipse { > semiaxis_x: a, >@@ -302,38 +301,38 @@ where > PositionComponent::Side(keyword, None) => { > // left | top => 0% > // right | bottom => 100% > let p = if keyword.is_start() { 0. } else { 1. }; > ( > S::start(), > Cow::Owned(LengthOrPercentage::Percentage(Percentage(p))), > ) >- }, >+ } > PositionComponent::Side(keyword, Some(ref lop)) if !keyword.is_start() => { > if let LengthOrPercentage::Percentage(p) = *to_non_zero_length(lop) { > ( > S::start(), > Cow::Owned(LengthOrPercentage::Percentage(Percentage(1. - p.0))), > ) > } else { > (keyword, Cow::Borrowed(lop)) > } >- }, >+ } > PositionComponent::Length(ref lop) | PositionComponent::Side(_, Some(ref lop)) => { > (S::start(), to_non_zero_length(lop)) >- }, >+ } > } > } > > fn to_non_zero_length(lop: &LengthOrPercentage) -> Cow<LengthOrPercentage> { > match *lop { > LengthOrPercentage::Length(ref l) if l.is_zero() => { > Cow::Owned(LengthOrPercentage::Percentage(Percentage(0.))) >- }, >+ } > _ => Cow::Borrowed(lop), > } > } > > fn write_pair<A, B, W>(a: &A, b: &B, dest: &mut CssWriter<W>) -> fmt::Result > where > A: ToCss, > B: ToCss, >@@ -372,18 +371,17 @@ impl Polygon { > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let fill = input > .try(|i| -> Result<_, ParseError> { > let fill = FillRule::parse(i)?; > i.expect_comma()?; // only eat the comma if there is something before it > Ok(fill) >- }) >- .unwrap_or_default(); >+ }).unwrap_or_default(); > > let buf = input.parse_comma_separated(|i| { > Ok(( > LengthOrPercentage::parse(context, i)?, > LengthOrPercentage::parse(context, i)?, > )) > })?; > >diff --git a/servo/components/style/values/specified/border.rs b/servo/components/style/values/specified/border.rs >index 0713ed99eb94..21d774c2fe5b 100644 >--- a/servo/components/style/values/specified/border.rs >+++ b/servo/components/style/values/specified/border.rs >@@ -11,18 +11,18 @@ use style_traits::{CssWriter, ParseError, ToCss}; > use values::computed::{self, Context, ToComputedValue}; > use values::generics::border::BorderCornerRadius as GenericBorderCornerRadius; > use values::generics::border::BorderImageSideWidth as GenericBorderImageSideWidth; > use values::generics::border::BorderImageSlice as GenericBorderImageSlice; > use values::generics::border::BorderRadius as GenericBorderRadius; > use values::generics::border::BorderSpacing as GenericBorderSpacing; > use values::generics::rect::Rect; > use values::generics::size::Size; >-use values::specified::{AllowQuirks, Number, NumberOrPercentage}; > use values::specified::length::{Length, LengthOrPercentage, NonNegativeLength}; >+use values::specified::{AllowQuirks, Number, NumberOrPercentage}; > > /// A specified value for a single side of the `border-width` property. > #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum BorderSideWidth { > /// `thin` > Thin, > /// `medium` > Medium, >@@ -184,30 +184,28 @@ impl Parse for BorderSpacing { > Length::parse_non_negative_quirky(context, input, AllowQuirks::Yes).map(From::from) > }).map(GenericBorderSpacing) > } > } > > /// A single border-image-repeat keyword. > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum BorderImageRepeatKeyword { > Stretch, > Repeat, > Round, > Space, > } > > /// The specified value for the `border-image-repeat` property. > /// > /// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword); > > impl ToCss for BorderImageRepeat { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > self.0.to_css(dest)?; >diff --git a/servo/components/style/values/specified/box.rs b/servo/components/style/values/specified/box.rs >index 6b474689df37..8fc8955f8f60 100644 >--- a/servo/components/style/values/specified/box.rs >+++ b/servo/components/style/values/specified/box.rs >@@ -1,69 +1,79 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified types for box properties. > >-use Atom; > use cssparser::Parser; > use custom_properties::Name as CustomPropertyName; > use parser::{Parse, ParserContext}; >-use properties::{LonghandId, ShorthandId, PropertyId, PropertyFlags, PropertyDeclarationId}; >+use properties::{LonghandId, PropertyDeclarationId, PropertyFlags, PropertyId, ShorthandId}; > use selectors::parser::SelectorParseErrorKind; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind, SpecifiedValueInfo, ToCss}; >-use values::{CustomIdent, KeyframesName}; >+use style_traits::{ >+ CssWriter, KeywordsCollectFn, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss, >+}; > use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; > use values::generics::box_::Perspective as GenericPerspective; > use values::generics::box_::VerticalAlign as GenericVerticalAlign; >-use values::specified::{AllowQuirks, Number}; > use values::specified::length::{LengthOrPercentage, NonNegativeLength}; >+use values::specified::{AllowQuirks, Number}; >+use values::{CustomIdent, KeyframesName}; >+use Atom; > > fn in_ua_or_chrome_sheet(context: &ParserContext) -> bool { > use stylesheets::Origin; >- context.stylesheet_origin == Origin::UserAgent || >- context.chrome_rules_enabled() >+ context.stylesheet_origin == Origin::UserAgent || context.chrome_rules_enabled() > } > > #[cfg(feature = "gecko")] > fn moz_display_values_enabled(context: &ParserContext) -> bool { > use gecko_bindings::structs; >- in_ua_or_chrome_sheet(context) || >- unsafe { >- structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled >- } >+ in_ua_or_chrome_sheet(context) >+ || unsafe { structs::StaticPrefs_sVarCache_layout_css_xul_display_values_content_enabled } > } > > #[cfg(feature = "gecko")] > fn moz_box_display_values_enabled(context: &ParserContext) -> bool { > use gecko_bindings::structs; >- in_ua_or_chrome_sheet(context) || >- unsafe { >- structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled >- } >+ in_ua_or_chrome_sheet(context) >+ || unsafe { >+ structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled >+ } > } > > /// Defines an elementâs display type, which consists of > /// the two basic qualities of how an element generates boxes > /// <https://drafts.csswg.org/css-display/#propdef-display> > /// > /// > /// NOTE(emilio): Order is important in Gecko! > /// > /// If you change it, make sure to take a look at the > /// FrameConstructionDataByDisplay stuff (both the XUL and non-XUL version), and > /// ensure it's still correct! > /// > /// Also, when you change this from Gecko you may need to regenerate the > /// C++-side bindings (see components/style/cbindgen.toml). > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ Hash, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] > #[repr(u8)] > pub enum Display { > None = 0, > Block, > #[cfg(feature = "gecko")] > FlowRoot, > Inline, >@@ -178,35 +188,38 @@ impl Display { > /// has a vastly different meaning. See bug 1107378 and bug 1407701. > /// > /// FIXME(emilio): This is a pretty decent hack, we should try to > /// remove it. > pub fn should_ignore_parsed_value(_old_display: Self, _new_display: Self) -> bool { > #[cfg(feature = "gecko")] > { > match (_old_display, _new_display) { >- (Display::WebkitBox, Display::MozBox) | >- (Display::WebkitInlineBox, Display::MozInlineBox) => { >+ (Display::WebkitBox, Display::MozBox) >+ | (Display::WebkitInlineBox, Display::MozInlineBox) => { > return true; >- }, >- _ => {}, >+ } >+ _ => {} > } > } > > return false; > } > > /// Returns whether this "display" value is one of the types for > /// ruby. > #[cfg(feature = "gecko")] > pub fn is_ruby_type(&self) -> bool { > matches!( > *self, >- Display::Ruby | Display::RubyBase | Display::RubyText | Display::RubyBaseContainer | >- Display::RubyTextContainer >+ Display::Ruby >+ | Display::RubyBase >+ | Display::RubyText >+ | Display::RubyBaseContainer >+ | Display::RubyTextContainer > ) > } > > /// Returns whether this "display" value is a ruby level container. > #[cfg(feature = "gecko")] > pub fn is_ruby_level_container(&self) -> bool { > matches!( > *self, >@@ -229,22 +242,22 @@ impl Display { > Display::WebkitInlineBox => Display::WebkitBox, > > // Special handling for contents and list-item on the root > // element for Gecko. > #[cfg(feature = "gecko")] > Display::Contents | Display::ListItem if _is_root_element => > { > Display::Block >- }, >+ } > > // These are not changed by blockification. > Display::None | Display::Block | Display::Flex | Display::ListItem | Display::Table => { > *self >- }, >+ } > > #[cfg(feature = "gecko")] > Display::Contents | Display::FlowRoot | Display::Grid | Display::WebkitBox => *self, > > // Everything else becomes block. > _ => Display::Block, > } > } >@@ -341,18 +354,17 @@ impl AnimationIterationCount { > /// Returns the value `1.0`. > #[inline] > pub fn one() -> Self { > GenericAnimationIterationCount::Number(Number::new(1.0)) > } > } > > /// A value for the `animation-name` property. >-#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > #[value_info(other_values = "none")] > pub struct AnimationName(pub Option<KeyframesName>); > > impl AnimationName { > /// Get the name of the animation as an `Atom`. > pub fn as_atom(&self) -> Option<&Atom> { > self.0.as_ref().map(|n| n.as_atom()) > } >@@ -386,45 +398,74 @@ impl Parse for AnimationName { > > input.expect_ident_matching("none")?; > Ok(AnimationName(None)) > } > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum ScrollSnapType { > None, > Mandatory, > Proximity, > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum OverscrollBehavior { > Auto, > Contain, > None, > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum OverflowClipBox { > PaddingBox, > ContentBox, > } > >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > /// Provides a rendering hint to the user agent, > /// stating what kinds of changes the author expects > /// to perform on the element > /// > /// <https://drafts.csswg.org/css-will-change/#will-change> > pub enum WillChange { > /// Expresses no particular intent > Auto, >@@ -492,21 +533,21 @@ fn change_bits_for_longhand(longhand: LonghandId) -> WillChangeBits { > > fn change_bits_for_maybe_property(ident: &str, context: &ParserContext) -> WillChangeBits { > let id = match PropertyId::parse_ignoring_rule_type(ident, context) { > Ok(id) => id, > Err(..) => return WillChangeBits::empty(), > }; > > match id.as_shorthand() { >- Ok(shorthand) => { >- shorthand.longhands().fold(WillChangeBits::empty(), |flags, p| { >+ Ok(shorthand) => shorthand >+ .longhands() >+ .fold(WillChangeBits::empty(), |flags, p| { > flags | change_bits_for_longhand(p) >- }) >- } >+ }), > Err(PropertyDeclarationId::Longhand(longhand)) => change_bits_for_longhand(longhand), > Err(PropertyDeclarationId::Custom(..)) => WillChangeBits::empty(), > } > } > > impl Parse for WillChange { > /// auto | <animateable-feature># > fn parse<'i, 't>( >@@ -576,22 +617,21 @@ impl ToCss for TouchAction { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > match *self { > TouchAction::TOUCH_ACTION_NONE => dest.write_str("none"), > TouchAction::TOUCH_ACTION_AUTO => dest.write_str("auto"), > TouchAction::TOUCH_ACTION_MANIPULATION => dest.write_str("manipulation"), >- _ if self.contains( >- TouchAction::TOUCH_ACTION_PAN_X | TouchAction::TOUCH_ACTION_PAN_Y, >- ) => >+ _ if self >+ .contains(TouchAction::TOUCH_ACTION_PAN_X | TouchAction::TOUCH_ACTION_PAN_Y) => > { > dest.write_str("pan-x pan-y") >- }, >+ } > _ if self.contains(TouchAction::TOUCH_ACTION_PAN_X) => dest.write_str("pan-x"), > _ if self.contains(TouchAction::TOUCH_ACTION_PAN_Y) => dest.write_str("pan-y"), > _ => panic!("invalid touch-action value"), > } > } > } > > impl Parse for TouchAction { >@@ -726,17 +766,17 @@ impl Parse for Contain { > "none" if result.is_empty() => return Ok(result), > _ => None > }; > > let flag = match flag { > Some(flag) if !result.contains(flag) => flag, > _ => { > return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name))) >- }, >+ } > }; > result.insert(flag); > } > > if !result.is_empty() { > Ok(result) > } else { > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >@@ -751,18 +791,17 @@ impl Parse for Perspective { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > if input.try(|i| i.expect_ident_matching("none")).is_ok() { > return Ok(GenericPerspective::None); > } > Ok(GenericPerspective::Length(NonNegativeLength::parse( >- context, >- input, >+ context, input, > )?)) > } > } > > /// A given transition property, that is either `All`, a longhand or shorthand > /// property, or an unsupported or custom property. > #[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue)] > pub enum TransitionProperty { >@@ -800,31 +839,31 @@ impl Parse for TransitionProperty { > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let location = input.current_source_location(); > let ident = input.expect_ident()?; > > let id = match PropertyId::parse_ignoring_rule_type(&ident, context) { > Ok(id) => id, >- Err(..) => return Ok(TransitionProperty::Unsupported( >- CustomIdent::from_ident(location, ident, &["none"])?, >- )), >+ Err(..) => { >+ return Ok(TransitionProperty::Unsupported(CustomIdent::from_ident( >+ location, >+ ident, >+ &["none"], >+ )?)) >+ } > }; > > Ok(match id.as_shorthand() { > Ok(s) => TransitionProperty::Shorthand(s), >- Err(longhand_or_custom) => { >- match longhand_or_custom { >- PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), >- PropertyDeclarationId::Custom(custom) => { >- TransitionProperty::Custom(custom.clone()) >- } >- } >- } >+ Err(longhand_or_custom) => match longhand_or_custom { >+ PropertyDeclarationId::Longhand(id) => TransitionProperty::Longhand(id), >+ PropertyDeclarationId::Custom(custom) => TransitionProperty::Custom(custom.clone()), >+ }, > }) > } > } > > impl SpecifiedValueInfo for TransitionProperty { > fn collect_completion_keywords(f: KeywordsCollectFn) { > // `transition-property` can actually accept all properties and > // arbitrary identifiers, but `all` is a special one we'd like >@@ -844,56 +883,58 @@ impl TransitionProperty { > #[cfg(feature = "gecko")] > pub fn to_nscsspropertyid(&self) -> Result<::gecko_bindings::structs::nsCSSPropertyID, ()> { > Ok(match *self { > TransitionProperty::Shorthand(ShorthandId::All) => { > ::gecko_bindings::structs::nsCSSPropertyID::eCSSPropertyExtra_all_properties > } > TransitionProperty::Shorthand(ref id) => id.to_nscsspropertyid(), > TransitionProperty::Longhand(ref id) => id.to_nscsspropertyid(), >- TransitionProperty::Custom(..) | >- TransitionProperty::Unsupported(..) => return Err(()), >+ TransitionProperty::Custom(..) | TransitionProperty::Unsupported(..) => return Err(()), > }) > } > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, >+)] > /// https://drafts.csswg.org/css-box/#propdef-float > pub enum Float { > Left, > Right, > None, > // https://drafts.csswg.org/css-logical-props/#float-clear > InlineStart, >- InlineEnd >+ InlineEnd, > } > > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, >+)] > /// https://drafts.csswg.org/css-box/#propdef-clear > pub enum Clear { > None, > Left, > Right, > Both, > // https://drafts.csswg.org/css-logical-props/#float-clear > InlineStart, >- InlineEnd >+ InlineEnd, > } > > /// https://drafts.csswg.org/css-ui/#propdef-resize > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss, >+)] > pub enum Resize { > None, > Both, > Horizontal, > Vertical, > // https://drafts.csswg.org/css-logical-1/#resize > Inline, > Block, >@@ -901,18 +942,29 @@ pub enum Resize { > > /// The value for the `appearance` property. > /// > /// https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-appearance > /// > /// NOTE(emilio): When changing this you may want to regenerate the C++ bindings > /// (see components/style/cbindgen.toml) > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss, ToComputedValue)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ Hash, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToCss, >+ ToComputedValue, >+)] > #[repr(u8)] > pub enum Appearance { > /// No appearance at all. > None, > /// A typical dialog button. > Button, > /// Various arrows that go in buttons > ButtonArrowDown, >diff --git a/servo/components/style/values/specified/calc.rs b/servo/components/style/values/specified/calc.rs >index 06c1dba29559..ece8dcb814c7 100644 >--- a/servo/components/style/values/specified/calc.rs >+++ b/servo/components/style/values/specified/calc.rs >@@ -4,23 +4,23 @@ > > //! [Calc expressions][calc]. > //! > //! [calc]: https://drafts.csswg.org/css-values/#calc-notation > > use cssparser::{AngleOrNumber, NumberOrPercentage, Parser, Token}; > use parser::ParserContext; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use style_traits::values::specified::AllowedNumericType; >-use values::{CSSFloat, CSSInteger}; >+use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use values::computed; >-use values::specified::{Angle, Time}; >-use values::specified::length::{AbsoluteLength, FontRelativeLength, NoCalcLength}; > use values::specified::length::ViewportPercentageLength; >+use values::specified::length::{AbsoluteLength, FontRelativeLength, NoCalcLength}; >+use values::specified::{Angle, Time}; >+use values::{CSSFloat, CSSInteger}; > > /// A node inside a `Calc` expression's AST. > #[derive(Clone, Debug)] > pub enum CalcNode { > /// `<length>` > Length(NoCalcLength), > /// `<angle>` > Angle(Angle), >@@ -168,53 +168,53 @@ impl CalcNode { > // FIXME: remove early returns when lifetimes are non-lexical > match (input.next()?, expected_unit) { > (&Token::Number { value, .. }, _) => return Ok(CalcNode::Number(value)), > ( > &Token::Dimension { > value, ref unit, .. > }, > CalcUnit::Length, >- ) | >- ( >+ ) >+ | ( > &Token::Dimension { > value, ref unit, .. > }, > CalcUnit::LengthOrPercentage, > ) => { > return NoCalcLength::parse_dimension(context, value, unit) > .map(CalcNode::Length) > .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >- }, >+ } > ( > &Token::Dimension { > value, ref unit, .. > }, > CalcUnit::Angle, > ) => { > return Angle::parse_dimension(value, unit, /* from_calc = */ true) > .map(CalcNode::Angle) > .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >- }, >+ } > ( > &Token::Dimension { > value, ref unit, .. > }, > CalcUnit::Time, > ) => { > return Time::parse_dimension(value, unit, /* from_calc = */ true) > .map(CalcNode::Time) > .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >- }, >- (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) | >- (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { >+ } >+ (&Token::Percentage { unit_value, .. }, CalcUnit::LengthOrPercentage) >+ | (&Token::Percentage { unit_value, .. }, CalcUnit::Percentage) => { > return Ok(CalcNode::Percentage(unit_value)) >- }, >- (&Token::ParenthesisBlock, _) => {}, >- (&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ (&Token::ParenthesisBlock, _) => {} >+ (&Token::Function(ref name), _) if name.eq_ignore_ascii_case("calc") => {} > (t, _) => return Err(location.new_unexpected_token_error(t.clone())), > } > input.parse_nested_block(|i| CalcNode::parse(context, i, expected_unit)) > } > > /// Parse a top-level `calc` expression, with all nested sub-expressions. > /// > /// This is in charge of parsing, for example, `2 + 3 * 100%`. >@@ -233,29 +233,29 @@ impl CalcNode { > break; // allow trailing whitespace > } > // FIXME: remove clone() when lifetimes are non-lexical > match input.next()?.clone() { > Token::Delim('+') => { > let rhs = Self::parse_product(context, input, expected_unit)?; > let new_root = CalcNode::Sum(Box::new(root), Box::new(rhs)); > root = new_root; >- }, >+ } > Token::Delim('-') => { > let rhs = Self::parse_product(context, input, expected_unit)?; > let new_root = CalcNode::Sub(Box::new(root), Box::new(rhs)); > root = new_root; >- }, >+ } > t => return Err(input.new_unexpected_token_error(t)), > } >- }, >+ } > _ => { > input.reset(&start); > break; >- }, >+ } > } > } > > Ok(root) > } > > /// Parse a top-level `calc` expression, and all the products that may > /// follow, and stop as soon as a non-product expression is found. >@@ -275,27 +275,27 @@ impl CalcNode { > > loop { > let start = input.state(); > match input.next() { > Ok(&Token::Delim('*')) => { > let rhs = Self::parse_one(context, input, expected_unit)?; > let new_root = CalcNode::Mul(Box::new(root), Box::new(rhs)); > root = new_root; >- }, >+ } > // TODO(emilio): Figure out why the `Integer` check. > Ok(&Token::Delim('/')) if expected_unit != CalcUnit::Integer => { > let rhs = Self::parse_one(context, input, expected_unit)?; > let new_root = CalcNode::Div(Box::new(root), Box::new(rhs)); > root = new_root; >- }, >+ } > _ => { > input.reset(&start); > break; >- }, >+ } > } > } > > Ok(root) > } > > /// Tries to simplify this expression into a `<length>` or `<percentage`> > /// value. >@@ -316,35 +316,35 @@ impl CalcNode { > Ok(match *self { > CalcNode::Percentage(percentage) => percentage, > CalcNode::Sub(ref a, ref b) => a.to_percentage()? - b.to_percentage()?, > CalcNode::Sum(ref a, ref b) => a.to_percentage()? + b.to_percentage()?, > CalcNode::Mul(ref a, ref b) => match a.to_percentage() { > Ok(lhs) => { > let rhs = b.to_number()?; > lhs * rhs >- }, >+ } > Err(..) => { > let lhs = a.to_number()?; > let rhs = b.to_percentage()?; > lhs * rhs >- }, >+ } > }, > CalcNode::Div(ref a, ref b) => { > let lhs = a.to_percentage()?; > let rhs = b.to_number()?; > if rhs == 0. { > return Err(()); > } > lhs / rhs >- }, >- CalcNode::Number(..) | >- CalcNode::Length(..) | >- CalcNode::Angle(..) | >- CalcNode::Time(..) => return Err(()), >+ } >+ CalcNode::Number(..) >+ | CalcNode::Length(..) >+ | CalcNode::Angle(..) >+ | CalcNode::Time(..) => return Err(()), > }) > } > > /// Puts this `<length>` or `<percentage>` into `ret`, or error. > /// > /// `factor` is the sign or multiplicative factor to account for the sign > /// (this allows adding and substracting into the return value). > fn add_length_or_percentage_to( >@@ -352,161 +352,161 @@ impl CalcNode { > ret: &mut CalcLengthOrPercentage, > factor: CSSFloat, > ) -> Result<(), ()> { > match *self { > CalcNode::Percentage(pct) => { > ret.percentage = Some(computed::Percentage( > ret.percentage.map_or(0., |p| p.0) + pct * factor, > )); >- }, >+ } > CalcNode::Length(ref l) => match *l { > NoCalcLength::Absolute(abs) => { > ret.absolute = Some(match ret.absolute { > Some(value) => value + abs * factor, > None => abs * factor, > }); >- }, >+ } > NoCalcLength::FontRelative(rel) => match rel { > FontRelativeLength::Em(em) => { > ret.em = Some(ret.em.unwrap_or(0.) + em * factor); >- }, >+ } > FontRelativeLength::Ex(ex) => { > ret.ex = Some(ret.ex.unwrap_or(0.) + ex * factor); >- }, >+ } > FontRelativeLength::Ch(ch) => { > ret.ch = Some(ret.ch.unwrap_or(0.) + ch * factor); >- }, >+ } > FontRelativeLength::Rem(rem) => { > ret.rem = Some(ret.rem.unwrap_or(0.) + rem * factor); >- }, >+ } > }, > NoCalcLength::ViewportPercentage(rel) => match rel { > ViewportPercentageLength::Vh(vh) => { > ret.vh = Some(ret.vh.unwrap_or(0.) + vh * factor) >- }, >+ } > ViewportPercentageLength::Vw(vw) => { > ret.vw = Some(ret.vw.unwrap_or(0.) + vw * factor) >- }, >+ } > ViewportPercentageLength::Vmax(vmax) => { > ret.vmax = Some(ret.vmax.unwrap_or(0.) + vmax * factor) >- }, >+ } > ViewportPercentageLength::Vmin(vmin) => { > ret.vmin = Some(ret.vmin.unwrap_or(0.) + vmin * factor) >- }, >+ } > }, > NoCalcLength::ServoCharacterWidth(..) => unreachable!(), > }, > CalcNode::Sub(ref a, ref b) => { > a.add_length_or_percentage_to(ret, factor)?; > b.add_length_or_percentage_to(ret, factor * -1.0)?; >- }, >+ } > CalcNode::Sum(ref a, ref b) => { > a.add_length_or_percentage_to(ret, factor)?; > b.add_length_or_percentage_to(ret, factor)?; >- }, >+ } > CalcNode::Mul(ref a, ref b) => match b.to_number() { > Ok(rhs) => { > a.add_length_or_percentage_to(ret, factor * rhs)?; >- }, >+ } > Err(..) => { > let lhs = a.to_number()?; > b.add_length_or_percentage_to(ret, factor * lhs)?; >- }, >+ } > }, > CalcNode::Div(ref a, ref b) => { > let new_factor = b.to_number()?; > if new_factor == 0. { > return Err(()); > } > a.add_length_or_percentage_to(ret, factor / new_factor)?; >- }, >+ } > CalcNode::Angle(..) | CalcNode::Time(..) | CalcNode::Number(..) => return Err(()), > } > > Ok(()) > } > > /// Tries to simplify this expression into a `<time>` value. > fn to_time(&self) -> Result<Time, ()> { > Ok(match *self { > CalcNode::Time(ref time) => time.clone(), > CalcNode::Sub(ref a, ref b) => { > let lhs = a.to_time()?; > let rhs = b.to_time()?; > Time::from_calc(lhs.seconds() - rhs.seconds()) >- }, >+ } > CalcNode::Sum(ref a, ref b) => { > let lhs = a.to_time()?; > let rhs = b.to_time()?; > Time::from_calc(lhs.seconds() + rhs.seconds()) >- }, >+ } > CalcNode::Mul(ref a, ref b) => match b.to_number() { > Ok(rhs) => { > let lhs = a.to_time()?; > Time::from_calc(lhs.seconds() * rhs) >- }, >+ } > Err(()) => { > let lhs = a.to_number()?; > let rhs = b.to_time()?; > Time::from_calc(lhs * rhs.seconds()) >- }, >+ } > }, > CalcNode::Div(ref a, ref b) => { > let lhs = a.to_time()?; > let rhs = b.to_number()?; > if rhs == 0. { > return Err(()); > } > Time::from_calc(lhs.seconds() / rhs) >- }, >- CalcNode::Number(..) | >- CalcNode::Length(..) | >- CalcNode::Percentage(..) | >- CalcNode::Angle(..) => return Err(()), >+ } >+ CalcNode::Number(..) >+ | CalcNode::Length(..) >+ | CalcNode::Percentage(..) >+ | CalcNode::Angle(..) => return Err(()), > }) > } > > /// Tries to simplify this expression into an `Angle` value. > fn to_angle(&self) -> Result<Angle, ()> { > Ok(match *self { > CalcNode::Angle(ref angle) => angle.clone(), > CalcNode::Sub(ref a, ref b) => { > let lhs = a.to_angle()?; > let rhs = b.to_angle()?; > Angle::from_calc(lhs.radians() - rhs.radians()) >- }, >+ } > CalcNode::Sum(ref a, ref b) => { > let lhs = a.to_angle()?; > let rhs = b.to_angle()?; > Angle::from_calc(lhs.radians() + rhs.radians()) >- }, >+ } > CalcNode::Mul(ref a, ref b) => match a.to_angle() { > Ok(lhs) => { > let rhs = b.to_number()?; > Angle::from_calc(lhs.radians() * rhs) >- }, >+ } > Err(..) => { > let lhs = a.to_number()?; > let rhs = b.to_angle()?; > Angle::from_calc(lhs * rhs.radians()) >- }, >+ } > }, > CalcNode::Div(ref a, ref b) => { > let lhs = a.to_angle()?; > let rhs = b.to_number()?; > if rhs == 0. { > return Err(()); > } > Angle::from_calc(lhs.radians() / rhs) >- }, >- CalcNode::Number(..) | >- CalcNode::Length(..) | >- CalcNode::Percentage(..) | >- CalcNode::Time(..) => return Err(()), >+ } >+ CalcNode::Number(..) >+ | CalcNode::Length(..) >+ | CalcNode::Percentage(..) >+ | CalcNode::Time(..) => return Err(()), > }) > } > > /// Tries to simplify this expression into a `<number>` value. > fn to_number(&self) -> Result<CSSFloat, ()> { > Ok(match *self { > CalcNode::Number(n) => n, > CalcNode::Sum(ref a, ref b) => a.to_number()? + b.to_number()?, >@@ -514,21 +514,21 @@ impl CalcNode { > CalcNode::Mul(ref a, ref b) => a.to_number()? * b.to_number()?, > CalcNode::Div(ref a, ref b) => { > let lhs = a.to_number()?; > let rhs = b.to_number()?; > if rhs == 0. { > return Err(()); > } > lhs / rhs >- }, >- CalcNode::Length(..) | >- CalcNode::Percentage(..) | >- CalcNode::Angle(..) | >- CalcNode::Time(..) => return Err(()), >+ } >+ CalcNode::Length(..) >+ | CalcNode::Percentage(..) >+ | CalcNode::Angle(..) >+ | CalcNode::Time(..) => return Err(()), > }) > } > > /// Convenience parsing function for integers. > pub fn parse_integer<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<CSSInteger, ParseError<'i>> { >diff --git a/servo/components/style/values/specified/color.rs b/servo/components/style/values/specified/color.rs >index c05f0ddce0ef..bbe1b1824e40 100644 >--- a/servo/components/style/values/specified/color.rs >+++ b/servo/components/style/values/specified/color.rs >@@ -1,27 +1,27 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified color values. > >+use super::AllowQuirks; > use cssparser::{AngleOrNumber, Color as CSSParserColor, Parser, Token, RGBA}; > use cssparser::{BasicParseErrorKind, NumberOrPercentage, ParseErrorKind}; > #[cfg(feature = "gecko")] > use gecko_bindings::structs::nscolor; > use itoa; > use parser::{Parse, ParserContext}; > #[cfg(feature = "gecko")] > use properties::longhands::system_colors::SystemColor; > use std::fmt::{self, Write}; > use std::io::Write as IoWrite; > use style_traits::{CssType, CssWriter, KeywordsCollectFn, ParseError, StyleParseErrorKind}; > use style_traits::{SpecifiedValueInfo, ToCss, ValueParseErrorKind}; >-use super::AllowQuirks; > use values::computed::{Color as ComputedColor, Context, ToComputedValue}; > use values::generics::color::Color as GenericColor; > use values::specified::calc::CalcNode; > > /// Specified color value > #[derive(Clone, Debug, MallocSizeOf, PartialEq)] > pub enum Color { > /// The 'currentColor' keyword >diff --git a/servo/components/style/values/specified/column.rs b/servo/components/style/values/specified/column.rs >index d065835423d6..4cd8ad0777f0 100644 >--- a/servo/components/style/values/specified/column.rs >+++ b/servo/components/style/values/specified/column.rs >@@ -17,13 +17,12 @@ impl Parse for ColumnCount { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > if input.try(|i| i.expect_ident_matching("auto")).is_ok() { > return Ok(GenericColumnCount::Auto); > } > Ok(GenericColumnCount::Integer(PositiveInteger::parse( >- context, >- input, >+ context, input, > )?)) > } > } >diff --git a/servo/components/style/values/specified/counters.rs b/servo/components/style/values/specified/counters.rs >index ea369f9dec75..771551b7e95a 100644 >--- a/servo/components/style/values/specified/counters.rs >+++ b/servo/components/style/values/specified/counters.rs >@@ -5,27 +5,27 @@ > //! Specified types for counter properties. > > #[cfg(feature = "servo")] > use computed_values::list_style_type::T as ListStyleType; > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use style_traits::{ParseError, StyleParseErrorKind}; >-use values::CustomIdent; >-#[cfg(feature = "gecko")] >-use values::generics::CounterStyleOrNone; > use values::generics::counters as generics; > use values::generics::counters::CounterIncrement as GenericCounterIncrement; > use values::generics::counters::CounterPair; > use values::generics::counters::CounterReset as GenericCounterReset; > #[cfg(feature = "gecko")] >+use values::generics::CounterStyleOrNone; >+use values::specified::url::SpecifiedImageUrl; >+#[cfg(feature = "gecko")] > use values::specified::Attr; > use values::specified::Integer; >-use values::specified::url::SpecifiedImageUrl; >+use values::CustomIdent; > > /// A specified value for the `counter-increment` property. > pub type CounterIncrement = GenericCounterIncrement<Integer>; > > impl Parse for CounterIncrement { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -88,28 +88,26 @@ pub type ContentItem = generics::ContentItem<SpecifiedImageUrl>; > > impl Content { > #[cfg(feature = "servo")] > fn parse_counter_style(_: &ParserContext, input: &mut Parser) -> ListStyleType { > input > .try(|input| { > input.expect_comma()?; > ListStyleType::parse(input) >- }) >- .unwrap_or(ListStyleType::Decimal) >+ }).unwrap_or(ListStyleType::Decimal) > } > > #[cfg(feature = "gecko")] > fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyleOrNone { > input > .try(|input| { > input.expect_comma()?; > CounterStyleOrNone::parse(context, input) >- }) >- .unwrap_or(CounterStyleOrNone::decimal()) >+ }).unwrap_or(CounterStyleOrNone::decimal()) > } > } > > impl Parse for Content { > // normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote | > // no-close-quote ]+ > // TODO: <uri>, attr(<identifier>) > fn parse<'i, 't>( >@@ -148,17 +146,17 @@ impl Parse for Content { > } > } > // FIXME: remove clone() when lifetimes are non-lexical > match input.next().map(|t| t.clone()) { > Ok(Token::QuotedString(ref value)) => { > content.push(generics::ContentItem::String( > value.as_ref().to_owned().into_boxed_str(), > )); >- }, >+ } > Ok(Token::Function(ref name)) => { > let result = match_ignore_ascii_case! { &name, > "counter" => Some(input.parse_nested_block(|input| { > let location = input.current_source_location(); > let name = CustomIdent::from_ident(location, input.expect_ident()?, &[])?; > let style = Content::parse_counter_style(context, input); > Ok(generics::ContentItem::Counter(name, style)) > })), >@@ -177,30 +175,30 @@ impl Parse for Content { > _ => None > }; > match result { > Some(result) => content.push(result?), > None => { > return Err(input.new_custom_error( > StyleParseErrorKind::UnexpectedFunction(name.clone()), > )) >- }, >+ } > } >- }, >+ } > Ok(Token::Ident(ref ident)) => { > content.push(match_ignore_ascii_case! { &ident, > "open-quote" => generics::ContentItem::OpenQuote, > "close-quote" => generics::ContentItem::CloseQuote, > "no-open-quote" => generics::ContentItem::NoOpenQuote, > "no-close-quote" => generics::ContentItem::NoCloseQuote, > _ => return Err(input.new_custom_error( > SelectorParseErrorKind::UnexpectedIdent(ident.clone()) > )) > }); >- }, >+ } > Err(_) => break, > Ok(t) => return Err(input.new_unexpected_token_error(t)), > } > } > if content.is_empty() { > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > Ok(generics::Content::Items(content.into_boxed_slice())) >diff --git a/servo/components/style/values/specified/effects.rs b/servo/components/style/values/specified/effects.rs >index c3304b05af0a..65b27cc7dca0 100644 >--- a/servo/components/style/values/specified/effects.rs >+++ b/servo/components/style/values/specified/effects.rs >@@ -2,30 +2,30 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified types for CSS values related to effects. > > use cssparser::{self, BasicParseErrorKind, Parser, Token}; > use parser::{Parse, ParserContext}; > use style_traits::{ParseError, StyleParseErrorKind, ValueParseErrorKind}; >-#[cfg(not(feature = "gecko"))] >-use values::Impossible; >-use values::computed::{Context, NonNegativeNumber as ComputedNonNegativeNumber, ToComputedValue}; > use values::computed::effects::BoxShadow as ComputedBoxShadow; > use values::computed::effects::SimpleShadow as ComputedSimpleShadow; >-use values::generics::NonNegative; >+use values::computed::{Context, NonNegativeNumber as ComputedNonNegativeNumber, ToComputedValue}; > use values::generics::effects::BoxShadow as GenericBoxShadow; > use values::generics::effects::Filter as GenericFilter; > use values::generics::effects::SimpleShadow as GenericSimpleShadow; >-use values::specified::{Angle, NumberOrPercentage}; >+use values::generics::NonNegative; > use values::specified::color::Color; > use values::specified::length::{Length, NonNegativeLength}; > #[cfg(feature = "gecko")] > use values::specified::url::SpecifiedUrl; >+use values::specified::{Angle, NumberOrPercentage}; >+#[cfg(not(feature = "gecko"))] >+use values::Impossible; > > /// A specified value for a single shadow of the `box-shadow` property. > pub type BoxShadow = > GenericBoxShadow<Option<Color>, Length, Option<NonNegativeLength>, Option<Length>>; > > /// A specified value for a single `filter`. > #[cfg(feature = "gecko")] > pub type Filter = GenericFilter<Angle, Factor, NonNegativeLength, SimpleShadow, SpecifiedUrl>; >@@ -49,20 +49,20 @@ impl Factor { > } > > /// Clamp the value to 1 if the value is over 100%. > #[inline] > fn clamp_to_one(self) -> Self { > match self.0 { > NumberOrPercentage::Percentage(percent) => { > Factor(NumberOrPercentage::Percentage(percent.clamp_to_hundred())) >- }, >+ } > NumberOrPercentage::Number(number) => { > Factor(NumberOrPercentage::Number(number.clamp_to_one())) >- }, >+ } > } > } > } > > impl Parse for Factor { > #[inline] > fn parse<'i, 't>( > context: &ParserContext, >@@ -113,23 +113,23 @@ impl Parse for BoxShadow { > inset = true; > continue; > } > } > if lengths.is_none() { > let value = input.try::<_, _, ParseError>(|i| { > let horizontal = Length::parse(context, i)?; > let vertical = Length::parse(context, i)?; >- let (blur, spread) = match i.try::<_, _, ParseError>(|i| { >- Length::parse_non_negative(context, i) >- }) { >+ let (blur, spread) = match i >+ .try::<_, _, ParseError>(|i| Length::parse_non_negative(context, i)) >+ { > Ok(blur) => { > let spread = i.try(|i| Length::parse(context, i)).ok(); > (Some(blur.into()), spread) >- }, >+ } > Err(_) => (None, None), > }; > Ok((horizontal, vertical, blur, spread)) > }); > if let Ok(value) = value { > lengths = Some(value); > continue; > } >@@ -138,17 +138,18 @@ impl Parse for BoxShadow { > if let Ok(value) = input.try(|i| Color::parse(context, i)) { > color = Some(value); > continue; > } > } > break; > } > >- let lengths = lengths.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?; >+ let lengths = >+ lengths.ok_or(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))?; > Ok(BoxShadow { > base: SimpleShadow { > color: color, > horizontal: lengths.0, > vertical: lengths.1, > blur: lengths.2, > }, > spread: lengths.3, >@@ -159,17 +160,18 @@ impl Parse for BoxShadow { > > impl ToComputedValue for BoxShadow { > type ComputedValue = ComputedBoxShadow; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > ComputedBoxShadow { > base: self.base.to_computed_value(context), >- spread: self.spread >+ spread: self >+ .spread > .as_ref() > .unwrap_or(&Length::zero()) > .to_computed_value(context), > inset: self.inset, > } > } > > #[inline] >@@ -266,23 +268,25 @@ impl Parse for SimpleShadow { > } > > impl ToComputedValue for SimpleShadow { > type ComputedValue = ComputedSimpleShadow; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > ComputedSimpleShadow { >- color: self.color >+ color: self >+ .color > .as_ref() > .unwrap_or(&Color::currentcolor()) > .to_computed_value(context), > horizontal: self.horizontal.to_computed_value(context), > vertical: self.vertical.to_computed_value(context), >- blur: self.blur >+ blur: self >+ .blur > .as_ref() > .unwrap_or(&NonNegativeLength::zero()) > .to_computed_value(context), > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { >diff --git a/servo/components/style/values/specified/font.rs b/servo/components/style/values/specified/font.rs >index 8d8355821e8c..45f78da081d2 100644 >--- a/servo/components/style/values/specified/font.rs >+++ b/servo/components/style/values/specified/font.rs >@@ -1,37 +1,39 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified values for font properties > >-use Atom; > use app_units::Au; > use byteorder::{BigEndian, ByteOrder}; > use cssparser::{Parser, Token}; > #[cfg(feature = "gecko")] > use gecko_bindings::bindings; > #[cfg(feature = "gecko")] > use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; > use parser::{Parse, ParserContext}; > use properties::longhands::system_font::SystemFont; > use std::fmt::{self, Write}; >+use style_traits::values::SequenceWriter; > use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; > use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; >-use style_traits::values::SequenceWriter; >-use values::CustomIdent; >-use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage}; >-use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue}; > use values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily}; >-use values::generics::NonNegative; >-use values::generics::font::{KeywordSize, VariationValue}; >+use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue}; >+use values::computed::{Angle as ComputedAngle, Percentage as ComputedPercentage}; > use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag}; >-use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage}; >+use values::generics::font::{KeywordSize, VariationValue}; >+use values::generics::NonNegative; > use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX}; >+use values::specified::{ >+ AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage, >+}; >+use values::CustomIdent; >+use Atom; > > // FIXME(emilio): The system font code is copy-pasta, and should be cleaned up. > macro_rules! system_font_methods { > ($ty:ident, $field:ident) => { > system_font_methods!($ty); > > fn compute_system(&self, _context: &Context) -> <$ty as ToComputedValue>::ComputedValue { > debug_assert!(matches!(*self, $ty::System(..))); >@@ -143,19 +145,19 @@ impl ToComputedValue for FontWeight { > .clone_font_weight() > .lighter(), > FontWeight::System(_) => self.compute_system(context), > } > } > > #[inline] > fn from_computed_value(computed: &computed::FontWeight) -> Self { >- FontWeight::Absolute(AbsoluteFontWeight::Weight( >- Number::from_computed_value(&computed.0) >- )) >+ FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::from_computed_value( >+ &computed.0, >+ ))) > } > } > > /// An absolute font-weight value for a @font-face rule. > /// > /// https://drafts.csswg.org/css-fonts-4/#font-weight-absolute-values > #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum AbsoluteFontWeight { >@@ -169,42 +171,39 @@ pub enum AbsoluteFontWeight { > Bold, > } > > impl AbsoluteFontWeight { > /// Returns the computed value for this absolute font weight. > pub fn compute(&self) -> computed::FontWeight { > match *self { > AbsoluteFontWeight::Weight(weight) => { >- computed::FontWeight( >- weight.get().max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT) >- ) >- }, >+ computed::FontWeight(weight.get().max(MIN_FONT_WEIGHT).min(MAX_FONT_WEIGHT)) >+ } > AbsoluteFontWeight::Normal => computed::FontWeight::normal(), > AbsoluteFontWeight::Bold => computed::FontWeight::bold(), > } > } > } > > impl Parse for AbsoluteFontWeight { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > if let Ok(number) = input.try(|input| Number::parse(context, input)) { > // We could add another AllowedNumericType value, but it doesn't > // seem worth it just for a single property with such a weird range, > // so we do the clamping here manually. >- if !number.was_calc() && >- (number.get() < MIN_FONT_WEIGHT || number.get() > MAX_FONT_WEIGHT) { >- return Err(input.new_custom_error( >- StyleParseErrorKind::UnspecifiedError >- )) >+ if !number.was_calc() >+ && (number.get() < MIN_FONT_WEIGHT || number.get() > MAX_FONT_WEIGHT) >+ { >+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } >- return Ok(AbsoluteFontWeight::Weight(number)) >+ return Ok(AbsoluteFontWeight::Weight(number)); > } > > Ok(try_match_ident_ignore_ascii_case! { input, > "normal" => AbsoluteFontWeight::Normal, > "bold" => AbsoluteFontWeight::Bold, > }) > } > } >@@ -270,17 +269,16 @@ impl ToComputedValue for SpecifiedFontStyle { > generics::FontStyle::Italic => generics::FontStyle::Italic, > generics::FontStyle::Oblique(ref angle) => { > generics::FontStyle::Oblique(Angle::from_computed_value(&angle.0)) > } > } > } > } > >- > /// The default angle for `font-style: oblique`. > /// > /// NOTE(emilio): As of right now this diverges from the spec, which specifies > /// 20, because it's not updated yet to account for the resolution in: > /// > /// https://github.com/w3c/csswg-drafts/issues/2295 > pub const DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES: f32 = 14.; > >@@ -294,55 +292,53 @@ pub const FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES: f32 = 90.; > > /// The minimum angle value that `font-style: oblique` should compute to. > pub const FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES: f32 = -90.; > > impl SpecifiedFontStyle { > /// Gets a clamped angle from a specified Angle. > pub fn compute_angle(angle: &Angle) -> ComputedAngle { > ComputedAngle::Deg( >- angle.degrees() >+ angle >+ .degrees() > .max(FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES) >- .min(FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES) >+ .min(FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES), > ) > } > > /// Parse a suitable angle for font-style: oblique. > pub fn parse_angle<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Angle, ParseError<'i>> { > let angle = Angle::parse(context, input)?; > if angle.was_calc() { > return Ok(angle); > } > > let degrees = angle.degrees(); >- if degrees < FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES || >- degrees > FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES >+ if degrees < FONT_STYLE_OBLIQUE_MIN_ANGLE_DEGREES >+ || degrees > FONT_STYLE_OBLIQUE_MAX_ANGLE_DEGREES > { >- return Err(input.new_custom_error( >- StyleParseErrorKind::UnspecifiedError >- )); >+ return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } >- return Ok(angle) >+ return Ok(angle); > } > > /// The default angle for `font-style: oblique`. > pub fn default_angle() -> Angle { > Angle::from_degrees( > DEFAULT_FONT_STYLE_OBLIQUE_ANGLE_DEGREES, > /* was_calc = */ false, > ) > } > } > > /// The specified value of the `font-style` property. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > #[allow(missing_docs)] > pub enum FontStyle { > Specified(SpecifiedFontStyle), > #[css(skip)] > System(SystemFont), > } > > impl FontStyle { >@@ -370,36 +366,36 @@ impl ToComputedValue for FontStyle { > } > } > > impl Parse for FontStyle { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { >- Ok(FontStyle::Specified(SpecifiedFontStyle::parse(context, input)?)) >+ Ok(FontStyle::Specified(SpecifiedFontStyle::parse( >+ context, input, >+ )?)) > } > } > > /// A value for the `font-stretch` property. > /// > /// https://drafts.csswg.org/css-fonts-4/#font-stretch-prop > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum FontStretch { > Stretch(Percentage), > Keyword(FontStretchKeyword), > #[css(skip)] > System(SystemFont), > } > > /// A keyword value for `font-stretch`. >-#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] > #[allow(missing_docs)] > pub enum FontStretchKeyword { > Normal, > Condensed, > UltraCondensed, > ExtraCondensed, > SemiCondensed, > SemiExpanded, >@@ -491,20 +487,18 @@ impl Parse for FontStretch { > > impl ToComputedValue for FontStretch { > type ComputedValue = computed::FontStretch; > > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > FontStretch::Stretch(ref percentage) => { > computed::FontStretch(NonNegative(percentage.to_computed_value(context))) >- }, >- FontStretch::Keyword(ref kw) => { >- computed::FontStretch(NonNegative(kw.compute())) >- }, >+ } >+ FontStretch::Keyword(ref kw) => computed::FontStretch(NonNegative(kw.compute())), > FontStretch::System(_) => self.compute_system(context), > } > } > > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > FontStretch::Stretch(Percentage::from_computed_value(&(computed.0).0)) > } > } >@@ -589,17 +583,17 @@ impl ToComputedValue for FontFamily { > #[cfg(feature = "gecko")] > impl MallocSizeOf for FontFamily { > fn size_of(&self, _ops: &mut MallocSizeOfOps) -> usize { > match *self { > FontFamily::Values(ref v) => { > // Although a SharedFontList object is refcounted, we always > // attribute its size to the specified value. > unsafe { bindings::Gecko_SharedFontList_SizeOfIncludingThis(v.0.get()) } >- }, >+ } > FontFamily::System(_) => 0, > } > } > } > > impl Parse for FontFamily { > /// <family-name># > /// <family-name> = <string> | [ <ident>+ ] >@@ -620,17 +614,17 @@ impl Parse for FamilyName { > fn parse<'i, 't>( > _: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > match SingleFontFamily::parse(input) { > Ok(SingleFontFamily::FamilyName(name)) => Ok(name), > Ok(SingleFontFamily::Generic(_)) => { > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >- }, >+ } > Err(e) => Err(e), > } > } > } > > #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > /// Preserve the readability of text when font fallback occurs > pub enum FontSizeAdjust { >@@ -656,27 +650,27 @@ impl FontSizeAdjust { > impl ToComputedValue for FontSizeAdjust { > type ComputedValue = computed::FontSizeAdjust; > > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > FontSizeAdjust::None => computed::FontSizeAdjust::None, > FontSizeAdjust::Number(ref n) => { > computed::FontSizeAdjust::Number(n.to_computed_value(context)) >- }, >+ } > FontSizeAdjust::System(_) => self.compute_system(context), > } > } > > fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self { > match *computed { > computed::FontSizeAdjust::None => FontSizeAdjust::None, > computed::FontSizeAdjust::Number(ref v) => { > FontSizeAdjust::Number(Number::from_computed_value(v)) >- }, >+ } > } > } > } > > impl Parse for FontSizeAdjust { > /// none | <number> > fn parse<'i, 't>( > context: &ParserContext, >@@ -685,18 +679,17 @@ impl Parse for FontSizeAdjust { > if input > .try(|input| input.expect_ident_matching("none")) > .is_ok() > { > return Ok(FontSizeAdjust::None); > } > > Ok(FontSizeAdjust::Number(Number::parse_non_negative( >- context, >- input, >+ context, input, > )?)) > } > } > > /// Additional information for specified keyword-derived font sizes. > pub type KeywordInfo = generics::KeywordInfo<NonNegativeLength>; > > impl KeywordInfo { >@@ -865,32 +858,32 @@ impl FontSize { > let size = match *self { > FontSize::Length(LengthOrPercentage::Length(NoCalcLength::FontRelative(value))) => { > if let FontRelativeLength::Em(em) = value { > // If the parent font was keyword-derived, this is too. > // Tack the em unit onto the factor > info = compose_keyword(em); > } > value.to_computed_value(context, base_size).into() >- }, >+ } > FontSize::Length(LengthOrPercentage::Length(NoCalcLength::ServoCharacterWidth( > value, > ))) => value.to_computed_value(base_size.resolve(context)).into(), > FontSize::Length(LengthOrPercentage::Length(NoCalcLength::Absolute(ref l))) => { > context.maybe_zoom_text(l.to_computed_value(context).into()) >- }, >+ } > FontSize::Length(LengthOrPercentage::Length(ref l)) => { > l.to_computed_value(context).into() >- }, >+ } > FontSize::Length(LengthOrPercentage::Percentage(pc)) => { > // If the parent font was keyword-derived, this is too. > // Tack the % onto the factor > info = compose_keyword(pc.0); > base_size.resolve(context).scale_by(pc.0).into() >- }, >+ } > FontSize::Length(LengthOrPercentage::Calc(ref calc)) => { > let parent = context.style().get_parent_font().clone_font_size(); > // if we contain em/% units and the parent was keyword derived, this is too > // Extract the ratio/offset and compose it > if (calc.em.is_some() || calc.percentage.is_some()) && parent.keyword_info.is_some() > { > let ratio = calc.em.unwrap_or(0.) + calc.percentage.map_or(0., |pc| pc.0); > // Compute it, but shave off the font-relative part (em, %). >@@ -901,56 +894,57 @@ impl FontSize { > // > // There's no particular "right answer" for what to do here, > // Gecko recascades as if the font had changed, we instead > // track the changes and reapply, which means that we carry > // over old computed ex/ch values whilst Gecko recomputes > // new ones. > // > // This is enough of an edge case to not really matter. >- let abs = calc.to_computed_value_zoomed( >- context, >- FontBaseSize::InheritedStyleButStripEmUnits, >- ).length_component(); >+ let abs = calc >+ .to_computed_value_zoomed( >+ context, >+ FontBaseSize::InheritedStyleButStripEmUnits, >+ ).length_component(); > > info = parent.keyword_info.map(|i| i.compose(ratio, abs.into())); > } > let calc = calc.to_computed_value_zoomed(context, base_size); > calc.to_used_value(Some(base_size.resolve(context))) > .unwrap() > .into() >- }, >+ } > FontSize::Keyword(i) => { > // As a specified keyword, this is keyword derived > info = Some(i); > i.to_computed_value(context) >- }, >+ } > FontSize::Smaller => { > info = compose_keyword(1. / LARGER_FONT_SIZE_RATIO); > FontRelativeLength::Em(1. / LARGER_FONT_SIZE_RATIO) > .to_computed_value(context, base_size) > .into() >- }, >+ } > FontSize::Larger => { > info = compose_keyword(LARGER_FONT_SIZE_RATIO); > FontRelativeLength::Em(LARGER_FONT_SIZE_RATIO) > .to_computed_value(context, base_size) > .into() >- }, >+ } > > FontSize::System(_) => { > #[cfg(feature = "servo")] > { > unreachable!() > } > #[cfg(feature = "gecko")] > { > context.cached_system_font.as_ref().unwrap().font_size.size > } >- }, >+ } > }; > computed::FontSize { > size: size, > keyword_info: info, > } > } > } > >@@ -1009,20 +1003,20 @@ impl FontSize { > mut computed: computed::FontSize, > ) { > // we could use clone_language and clone_font_family() here but that's > // expensive. Do it only in gecko mode for now. > #[cfg(feature = "gecko")] > { > // if the language or generic changed, we need to recalculate > // the font size from the stored font-size origin information. >- if context.builder.get_font().gecko().mLanguage.mRawPtr != >- context.builder.get_parent_font().gecko().mLanguage.mRawPtr || >- context.builder.get_font().gecko().mGenericID != >- context.builder.get_parent_font().gecko().mGenericID >+ if context.builder.get_font().gecko().mLanguage.mRawPtr >+ != context.builder.get_parent_font().gecko().mLanguage.mRawPtr >+ || context.builder.get_font().gecko().mGenericID >+ != context.builder.get_parent_font().gecko().mGenericID > { > if let Some(info) = computed.keyword_info { > computed.size = info.to_computed_value(context); > } > } > } > > let device = context.builder.device; >@@ -1107,22 +1101,22 @@ pub enum VariantAlternates { > pub struct VariantAlternatesList( > #[css(if_empty = "normal", iterable)] pub Box<[VariantAlternates]>, > ); > > impl VariantAlternatesList { > /// Returns the length of all variant alternates. > pub fn len(&self) -> usize { > self.0.iter().fold(0, |acc, alternate| match *alternate { >- VariantAlternates::Swash(_) | >- VariantAlternates::Stylistic(_) | >- VariantAlternates::Ornaments(_) | >- VariantAlternates::Annotation(_) => acc + 1, >- VariantAlternates::Styleset(ref slice) | >- VariantAlternates::CharacterVariant(ref slice) => acc + slice.len(), >+ VariantAlternates::Swash(_) >+ | VariantAlternates::Stylistic(_) >+ | VariantAlternates::Ornaments(_) >+ | VariantAlternates::Annotation(_) => acc + 1, >+ VariantAlternates::Styleset(ref slice) >+ | VariantAlternates::CharacterVariant(ref slice) => acc + slice.len(), > _ => acc, > }) > } > } > > #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > /// Control over the selection of these alternate glyphs > pub enum FontVariantAlternates { >@@ -1934,18 +1928,17 @@ impl Parse for FontFeatureSettings { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<FontFeatureSettings, ParseError<'i>> { > SpecifiedFontFeatureSettings::parse(context, input).map(FontFeatureSettings::Value) > } > } > >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > /// Whether user agents are allowed to synthesize bold or oblique font faces > /// when a font family lacks bold or italic faces > pub struct FontSynthesis { > /// If a `font-weight` is requested that the font family does not contain, > /// the user agent may synthesize the requested weight from the weights > /// that do exist in the font family. > #[css(represents_keyword)] > pub weight: bool, >@@ -2079,17 +2072,17 @@ impl ToComputedValue for FontLanguageOverride { > return computed::FontLanguageOverride(0); > } > let mut computed_lang = lang.to_string(); > while computed_lang.len() < 4 { > computed_lang.push(' '); > } > let bytes = computed_lang.into_bytes(); > computed::FontLanguageOverride(BigEndian::read_u32(&bytes)) >- }, >+ } > FontLanguageOverride::System(_) => self.compute_system(context), > } > } > #[inline] > fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self { > if computed.0 == 0 { > return FontLanguageOverride::Normal; > } >@@ -2212,36 +2205,36 @@ impl Parse for VariationValue<Number> { > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let tag = FontTag::parse(context, input)?; > let value = Number::parse(context, input)?; > Ok(Self { tag, value }) > } > } > >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > /// text-zoom. Enable if true, disable if false > pub struct XTextZoom(#[css(skip)] pub bool); > > impl Parse for XTextZoom { > fn parse<'i, 't>( > _: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<XTextZoom, ParseError<'i>> { > debug_assert!( > false, > "Should be set directly by presentation attributes only." > ); > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > /// Internal property that reflects the lang attribute > pub struct XLang(#[css(skip)] pub Atom); > > impl XLang { > #[inline] > /// Get default value for `-x-lang` > pub fn get_initial_value() -> XLang { > XLang(atom!("")) >@@ -2319,18 +2312,17 @@ impl Parse for MozScriptLevel { > return Ok(MozScriptLevel::Relative(i)); > } > input.expect_ident_matching("auto")?; > Ok(MozScriptLevel::Auto) > } > } > > #[cfg_attr(feature = "gecko", derive(MallocSizeOf))] >-#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, >- ToCss)] >+#[derive(Clone, Copy, Debug, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > /// Specifies the multiplier to be used to adjust font size > /// due to changes in scriptlevel. > /// > /// Ref: https://www.w3.org/TR/MathML3/chapter3.html#presm.mstyle.attrs > pub struct MozScriptSizeMultiplier(pub f32); > > impl MozScriptSizeMultiplier { > #[inline] >diff --git a/servo/components/style/values/specified/gecko.rs b/servo/components/style/values/specified/gecko.rs >index 847d632511e7..adb16c44cc8f 100644 >--- a/servo/components/style/values/specified/gecko.rs >+++ b/servo/components/style/values/specified/gecko.rs >@@ -4,18 +4,18 @@ > > //! Specified types for legacy Gecko-only properties. > > use cssparser::{Parser, Token}; > use gecko::values::GeckoStyleCoordConvertible; > use gecko_bindings::sugar::ns_style_coord::{CoordData, CoordDataMut}; > use parser::{Parse, ParserContext}; > use std::fmt; >-use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use style_traits::values::SequenceWriter; >+use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use values::computed; > use values::computed::length::CSSPixelLength; > use values::generics::gecko::ScrollSnapPoint as GenericScrollSnapPoint; > use values::generics::rect::Rect; > use values::specified::length::LengthOrPercentage; > > /// A specified type for scroll snap points. > pub type ScrollSnapPoint = GenericScrollSnapPoint<LengthOrPercentage>; >@@ -54,17 +54,17 @@ impl Parse for PixelOrPercentage { > let value = match *token { > Token::Dimension { > value, ref unit, .. > } => { > match_ignore_ascii_case! { unit, > "px" => Ok(PixelOrPercentage::Pixel(CSSPixelLength::new(value))), > _ => Err(()), > } >- }, >+ } > Token::Percentage { unit_value, .. } => Ok(PixelOrPercentage::Percentage( > computed::Percentage(unit_value), > )), > _ => Err(()), > }; > value.map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } >diff --git a/servo/components/style/values/specified/grid.rs b/servo/components/style/values/specified/grid.rs >index 830cccaf2e24..4e96f9e7b80e 100644 >--- a/servo/components/style/values/specified/grid.rs >+++ b/servo/components/style/values/specified/grid.rs >@@ -4,33 +4,34 @@ > > //! CSS handling for the computed value of > //! [grids](https://drafts.csswg.org/css-grid/) > > use cssparser::{ParseError as CssParseError, Parser, Token}; > use parser::{Parse, ParserContext}; > use std::mem; > use style_traits::{ParseError, StyleParseErrorKind}; >-use values::{CSSFloat, CustomIdent}; > use values::computed::{self, Context, ToComputedValue}; > use values::generics::grid::{GridTemplateComponent, RepeatCount, TrackBreadth}; > use values::generics::grid::{LineNameList, TrackKeyword, TrackRepeat, TrackSize}; > use values::generics::grid::{TrackList, TrackListType, TrackListValue}; > use values::specified::{Integer, LengthOrPercentage}; >+use values::{CSSFloat, CustomIdent}; > > /// Parse a single flexible length. > pub fn parse_flex<'i, 't>(input: &mut Parser<'i, 't>) -> Result<CSSFloat, ParseError<'i>> { > let location = input.current_source_location(); > match *input.next()? { > Token::Dimension { > value, ref unit, .. >- } if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() => >+ } >+ if unit.eq_ignore_ascii_case("fr") && value.is_sign_positive() => > { > Ok(value) >- }, >+ } > ref t => Err(location.new_unexpected_token_error(t.clone())), > } > } > > impl Parse for TrackBreadth<LengthOrPercentage> { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -59,29 +60,30 @@ impl Parse for TrackSize<LengthOrPercentage> { > if input.try(|i| i.expect_function_matching("minmax")).is_ok() { > return input.parse_nested_block(|input| { > let inflexible_breadth = > match input.try(|i| LengthOrPercentage::parse_non_negative(context, i)) { > Ok(lop) => TrackBreadth::Breadth(lop), > Err(..) => { > let keyword = TrackKeyword::parse(input)?; > TrackBreadth::Keyword(keyword) >- }, >+ } > }; > > input.expect_comma()?; > Ok(TrackSize::Minmax( > inflexible_breadth, > TrackBreadth::parse(context, input)?, > )) > }); > } > > input.expect_function_matching("fit-content")?; >- let lop = input.parse_nested_block(|i| LengthOrPercentage::parse_non_negative(context, i))?; >+ let lop = >+ input.parse_nested_block(|i| LengthOrPercentage::parse_non_negative(context, i))?; > Ok(TrackSize::FitContent(lop)) > } > } > > /// Parse the grid line names into a vector of owned strings. > /// > /// <https://drafts.csswg.org/css-grid/#typedef-line-names> > pub fn parse_line_names<'i, 't>( >@@ -170,17 +172,19 @@ impl TrackRepeat<LengthOrPercentage, Integer> { > .try(parse_line_names) > .unwrap_or(vec![].into_boxed_slice()), > ); > break; > } > } else { > if values.is_empty() { > // expecting at least one <track-size> >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::UnspecifiedError) >+ ); > } > > names.push(current_names); // final `<line-names>` > break; // no more <track-size>, breaking > } > } > > let repeat = TrackRepeat { >@@ -212,19 +216,21 @@ impl Parse for TrackList<LengthOrPercentage, Integer> { > // where idx points to the position of the <auto-repeat> in the track list. If there > // is any repeat before <auto-repeat>, we need to take the number of repetitions into > // account to set the position of <auto-repeat> so it remains the same while computing > // values. > let mut auto_offset = 0; > // assume that everything is <fixed-size>. This flag is useful when we encounter <auto-repeat> > let mut atleast_one_not_fixed = false; > loop { >- current_names.extend_from_slice(&mut input >- .try(parse_line_names) >- .unwrap_or(vec![].into_boxed_slice())); >+ current_names.extend_from_slice( >+ &mut input >+ .try(parse_line_names) >+ .unwrap_or(vec![].into_boxed_slice()), >+ ); > if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) { > if !track_size.is_fixed() { > atleast_one_not_fixed = true; > if auto_repeat.is_some() { > // <auto-track-list> only accepts <fixed-size> and <fixed-repeat> > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > } >@@ -239,31 +245,35 @@ impl Parse for TrackList<LengthOrPercentage, Integer> { > list_type = TrackListType::Normal; // <explicit-track-list> doesn't contain repeat() > } > > match type_ { > RepeatType::Normal => { > atleast_one_not_fixed = true; > if auto_repeat.is_some() { > // only <fixed-repeat> >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::UnspecifiedError) >+ ); > } >- }, >+ } > RepeatType::Auto => { > if auto_repeat.is_some() || atleast_one_not_fixed { > // We've either seen <auto-repeat> earlier, or there's at least one non-fixed value >- return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); >+ return Err( >+ input.new_custom_error(StyleParseErrorKind::UnspecifiedError) >+ ); > } > > list_type = TrackListType::Auto(values.len() as u16 + auto_offset); > auto_repeat = Some(repeat); > let vec = mem::replace(&mut current_names, vec![]); > names.push(vec.into_boxed_slice()); > continue; >- }, >+ } > RepeatType::Fixed => (), > } > > let vec = mem::replace(&mut current_names, vec![]); > names.push(vec.into_boxed_slice()); > if let RepeatCount::Number(num) = repeat.count { > auto_offset += (num.value() - 1) as u16; > } >@@ -312,42 +322,43 @@ impl ToComputedValue for TrackList<LengthOrPercentage, Integer> { > continue; > } > > match self.values[pos] { > TrackListValue::TrackSize(ref size) => { > let vec = mem::replace(&mut prev_names, vec![]); > line_names.push(vec.into_boxed_slice()); > values.push(TrackListValue::TrackSize(size.to_computed_value(context))); >- }, >+ } > TrackListValue::TrackRepeat(ref repeat) => { > // If the repeat count is numeric, we expand and merge the values. > let mut repeat = repeat.expand(); > let mut repeat_names_iter = repeat.line_names.iter(); > for (size, repeat_names) in > repeat.track_sizes.drain(..).zip(&mut repeat_names_iter) > { > prev_names.extend_from_slice(&repeat_names); > let vec = mem::replace(&mut prev_names, vec![]); > line_names.push(vec.into_boxed_slice()); > values.push(TrackListValue::TrackSize(size.to_computed_value(context))); > } > > if let Some(names) = repeat_names_iter.next() { > prev_names.extend_from_slice(&names); > } >- }, >+ } > } > } > > TrackList { > list_type: self.list_type.to_computed_value(context), > values: values, > line_names: line_names.into_boxed_slice(), >- auto_repeat: self.auto_repeat >+ auto_repeat: self >+ .auto_repeat > .clone() > .map(|repeat| repeat.to_computed_value(context)), > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > let mut values = Vec::with_capacity(computed.values.len() + 1); >diff --git a/servo/components/style/values/specified/image.rs b/servo/components/style/values/specified/image.rs >index 64d24573f4a7..7f026c8fcfe3 100644 >--- a/servo/components/style/values/specified/image.rs >+++ b/servo/components/style/values/specified/image.rs >@@ -2,38 +2,38 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! CSS handling for the specified value of > //! [`image`][image]s > //! > //! [image]: https://drafts.csswg.org/css-images/#image-values > >-use Atom; > use cssparser::{Parser, Token}; > use custom_properties::SpecifiedValue; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > #[cfg(feature = "servo")] > use servo_url::ServoUrl; > use std::cmp::Ordering; > use std::f32::consts::PI; > use std::fmt::{self, Write}; > use style_traits::{CssType, CssWriter, KeywordsCollectFn, ParseError}; >-use style_traits::{StyleParseErrorKind, SpecifiedValueInfo, ToCss}; >-use values::{Either, None_}; >+use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > #[cfg(feature = "gecko")] > use values::computed::{Context, Position as ComputedPosition, ToComputedValue}; >-use values::generics::image::{self as generic, Circle, CompatMode, Ellipse, ShapeExtent}; > use values::generics::image::PaintWorklet; >+use values::generics::image::{self as generic, Circle, CompatMode, Ellipse, ShapeExtent}; > use values::generics::position::Position as GenericPosition; >-use values::specified::{Angle, Color, Length, LengthOrPercentage}; >-use values::specified::{Number, NumberOrPercentage, Percentage}; > use values::specified::position::{LegacyPosition, Position, PositionComponent, Side, X, Y}; > use values::specified::url::SpecifiedImageUrl; >+use values::specified::{Angle, Color, Length, LengthOrPercentage}; >+use values::specified::{Number, NumberOrPercentage, Percentage}; >+use values::{Either, None_}; >+use Atom; > > /// A specified image layer. > pub type ImageLayer = Either<None_, Image>; > > /// Specified values for an image according to CSS-IMAGES. > /// <https://drafts.csswg.org/css-images/#image-values> > pub type Image = generic::Image<Gradient, MozImageRect, SpecifiedImageUrl>; > >@@ -50,29 +50,29 @@ pub type Gradient = > generic::Gradient<LineDirection, Length, LengthOrPercentage, GradientPosition, Color, Angle>; > > impl SpecifiedValueInfo for Gradient { > const SUPPORTED_TYPES: u8 = CssType::GRADIENT; > > fn collect_completion_keywords(f: KeywordsCollectFn) { > // This list here should keep sync with that in Gradient::parse. > f(&[ >- "linear-gradient", >- "-webkit-linear-gradient", >- "-moz-linear-gradient", >- "repeating-linear-gradient", >- "-webkit-repeating-linear-gradient", >- "-moz-repeating-linear-gradient", >- "radial-gradient", >- "-webkit-radial-gradient", >- "-moz-radial-gradient", >- "repeating-radial-gradient", >- "-webkit-repeating-radial-gradient", >- "-moz-repeating-radial-gradient", >- "-webkit-gradient", >+ "linear-gradient", >+ "-webkit-linear-gradient", >+ "-moz-linear-gradient", >+ "repeating-linear-gradient", >+ "-webkit-repeating-linear-gradient", >+ "-moz-repeating-linear-gradient", >+ "radial-gradient", >+ "-webkit-radial-gradient", >+ "-moz-radial-gradient", >+ "repeating-radial-gradient", >+ "-webkit-repeating-radial-gradient", >+ "-moz-repeating-radial-gradient", >+ "-webkit-gradient", > ]); > } > } > > /// A specified gradient kind. > #[cfg(not(feature = "gecko"))] > pub type GradientKind = > generic::GradientKind<LineDirection, Length, LengthOrPercentage, Position, Angle>; >@@ -228,25 +228,25 @@ impl Parse for Gradient { > }, > _ => None, > }; > > let (shape, repeating, mut compat_mode) = match result { > Some(result) => result, > None => { > return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func))) >- }, >+ } > }; > > #[cfg(feature = "gecko")] > { > use gecko_bindings::structs; >- if compat_mode == CompatMode::Moz && !unsafe { >- structs::StaticPrefs_sVarCache_layout_css_prefixes_gradients >- } { >+ if compat_mode == CompatMode::Moz >+ && !unsafe { structs::StaticPrefs_sVarCache_layout_css_prefixes_gradients } >+ { > return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedFunction(func))); > } > } > > let (kind, items) = input.parse_nested_block(|i| { > let shape = match shape { > Shape::Linear => GradientKind::parse_linear(context, i, &mut compat_mode)?, > Shape::Radial => GradientKind::parse_radial(context, i, &mut compat_mode)?, >@@ -292,24 +292,24 @@ impl Gradient { > }; > match (h, v) { > (Ordering::Less, Ordering::Less) => LineDirection::Corner(X::Right, Y::Bottom), > (Ordering::Less, Ordering::Equal) => LineDirection::Horizontal(X::Right), > (Ordering::Less, Ordering::Greater) => LineDirection::Corner(X::Right, Y::Top), > (Ordering::Equal, Ordering::Greater) => LineDirection::Vertical(Y::Top), > (Ordering::Equal, Ordering::Equal) | (Ordering::Equal, Ordering::Less) => { > LineDirection::Vertical(Y::Bottom) >- }, >+ } > (Ordering::Greater, Ordering::Less) => { > LineDirection::Corner(X::Left, Y::Bottom) >- }, >+ } > (Ordering::Greater, Ordering::Equal) => LineDirection::Horizontal(X::Left), > (Ordering::Greater, Ordering::Greater) => { > LineDirection::Corner(X::Left, Y::Top) >- }, >+ } > } > } > } > > impl From<Point> for Position { > fn from(point: Point) -> Self { > Self::new(point.horizontal.into(), point.vertical.into()) > } >@@ -336,48 +336,48 @@ impl Gradient { > Component::Number(number) => number, > Component::Side(side) => { > let p = if side.is_start() { > Percentage::zero() > } else { > Percentage::hundred() > }; > NumberOrPercentage::Percentage(p) >- }, >+ } > } > } > } > > impl<S: Side> From<Component<S>> for PositionComponent<S> { > fn from(component: Component<S>) -> Self { > match component { > Component::Center => PositionComponent::Center, > Component::Number(NumberOrPercentage::Number(number)) => { > PositionComponent::Length(Length::from_px(number.value).into()) >- }, >+ } > Component::Number(NumberOrPercentage::Percentage(p)) => { > PositionComponent::Length(p.into()) >- }, >+ } > Component::Side(side) => PositionComponent::Side(side, None), > } > } > } > > impl<S: Copy + Side> Component<S> { > fn partial_cmp(&self, other: &Self) -> Option<Ordering> { > match ( > NumberOrPercentage::from(*self), > NumberOrPercentage::from(*other), > ) { > (NumberOrPercentage::Percentage(a), NumberOrPercentage::Percentage(b)) => { > a.get().partial_cmp(&b.get()) >- }, >+ } > (NumberOrPercentage::Number(a), NumberOrPercentage::Number(b)) => { > a.value.partial_cmp(&b.value) >- }, >+ } > (_, _) => None, > } > } > } > > impl<S: Parse> Parse for Component<S> { > fn parse<'i, 't>( > context: &ParserContext, >@@ -507,20 +507,20 @@ impl Gradient { > &generic::GradientItem::ColorStop(ref a), > &generic::GradientItem::ColorStop(ref b), > ) => match (&a.position, &b.position) { > ( > &Some(LengthOrPercentage::Percentage(a)), > &Some(LengthOrPercentage::Percentage(b)), > ) => { > return a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal); >- }, >- _ => {}, >+ } >+ _ => {} > }, >- _ => {}, >+ _ => {} > } > if reverse_stops { > Ordering::Greater > } else { > Ordering::Less > } > }) > } >@@ -563,27 +563,27 @@ impl GradientKind { > let (shape, position, angle, moz_position) = match *compat_mode { > CompatMode::Modern => { > let shape = input.try(|i| EndingShape::parse(context, i, *compat_mode)); > let position = input.try(|i| { > i.expect_ident_matching("at")?; > Position::parse(context, i) > }); > (shape, position.ok(), None, None) >- }, >+ } > CompatMode::WebKit => { > let position = input.try(|i| Position::parse(context, i)); > let shape = input.try(|i| { > if position.is_ok() { > i.expect_comma()?; > } > EndingShape::parse(context, i, *compat_mode) > }); > (shape, position.ok(), None, None) >- }, >+ } > // The syntax of `-moz-` prefixed radial gradient is: > // -moz-radial-gradient( > // [ [ <position> || <angle> ]? [ ellipse | [ <length> | <percentage> ]{2} ] , | > // [ <position> || <angle> ]? [ [ circle | ellipse ] | <extent-keyword> ] , | > // ]? > // <color-stop> [ , <color-stop> ]+ > // ) > // where <extent-keyword> = closest-corner | closest-side | farthest-corner | farthest-side | >@@ -599,17 +599,17 @@ impl GradientKind { > let shape = input.try(|i| { > if position.is_ok() || angle.is_some() { > i.expect_comma()?; > } > EndingShape::parse(context, i, *compat_mode) > }); > > (shape, None, angle, position.ok()) >- }, >+ } > }; > > if shape.is_ok() || position.is_some() || angle.is_some() || moz_position.is_some() { > input.expect_comma()?; > } > > let shape = shape.unwrap_or({ > generic::EndingShape::Ellipse(Ellipse::Extent(ShapeExtent::FarthestCorner)) >@@ -676,62 +676,62 @@ impl generic::LineDirection for LineDirection { > let y = match *y { > OriginComponent::Side(Y::Top) => true, > OriginComponent::Length(LengthOrPercentage::Percentage( > ComputedPercentage(val), > )) => val == 0.0, > _ => false, > }; > x && y >- }, >+ } > _ => false, > } > } > > fn to_css<W>(&self, dest: &mut CssWriter<W>, compat_mode: CompatMode) -> fmt::Result > where > W: Write, > { > match *self { > LineDirection::Angle(angle) => angle.to_css(dest), > LineDirection::Horizontal(x) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > x.to_css(dest) >- }, >+ } > LineDirection::Vertical(y) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > y.to_css(dest) >- }, >+ } > LineDirection::Corner(x, y) => { > if compat_mode == CompatMode::Modern { > dest.write_str("to ")?; > } > x.to_css(dest)?; > dest.write_str(" ")?; > y.to_css(dest) >- }, >+ } > #[cfg(feature = "gecko")] > LineDirection::MozPosition(ref position, ref angle) => { > let mut need_space = false; > if let Some(ref position) = *position { > position.to_css(dest)?; > need_space = true; > } > if let Some(ref angle) = *angle { > if need_space { > dest.write_str(" ")?; > } > angle.to_css(dest)?; > } > Ok(()) >- }, >+ } > } > } > } > > impl LineDirection { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -755,21 +755,21 @@ impl LineDirection { > CompatMode::Modern => to_ident?, > // Fall back to Modern compatibility mode in case there is a `to` keyword. > // According to Gecko, `-moz-linear-gradient(to ...)` should serialize like > // `linear-gradient(to ...)`. > CompatMode::Moz if to_ident.is_ok() => *compat_mode = CompatMode::Modern, > // There is no `to` keyword in webkit prefixed syntax. If it's consumed, > // parsing should throw an error. > CompatMode::WebKit if to_ident.is_ok() => { >- return Err(i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent( >- "to".into(), >- ))) >- }, >- _ => {}, >+ return Err( >+ i.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("to".into())) >+ ) >+ } >+ _ => {} > } > > #[cfg(feature = "gecko")] > { > // `-moz-` prefixed linear gradient can be both Angle and Position. > if *compat_mode == CompatMode::Moz { > let position = i.try(|i| LegacyPosition::parse(context, i)).ok(); > if _angle.is_none() { >@@ -909,17 +909,17 @@ impl EndingShape { > impl ShapeExtent { > fn parse_with_compat_mode<'i, 't>( > input: &mut Parser<'i, 't>, > compat_mode: CompatMode, > ) -> Result<Self, ParseError<'i>> { > match Self::parse(input)? { > ShapeExtent::Contain | ShapeExtent::Cover if compat_mode == CompatMode::Modern => { > Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) >- }, >+ } > ShapeExtent::Contain => Ok(ShapeExtent::ClosestSide), > ShapeExtent::Cover => Ok(ShapeExtent::FarthestCorner), > keyword => Ok(keyword), > } > } > } > > impl GradientItem { >@@ -964,18 +964,17 @@ impl Parse for PaintWorklet { > ) -> Result<Self, ParseError<'i>> { > input.expect_function_matching("paint")?; > input.parse_nested_block(|input| { > let name = Atom::from(&**input.expect_ident()?); > let arguments = input > .try(|input| { > input.expect_comma()?; > input.parse_comma_separated(|input| SpecifiedValue::parse(input)) >- }) >- .unwrap_or(vec![]); >+ }).unwrap_or(vec![]); > Ok(PaintWorklet { name, arguments }) > }) > } > } > > impl Parse for MozImageRect { > fn parse<'i, 't>( > context: &ParserContext, >diff --git a/servo/components/style/values/specified/length.rs b/servo/components/style/values/specified/length.rs >index b6fe9bc23463..c8f3f0e65578 100644 >--- a/servo/components/style/values/specified/length.rs >+++ b/servo/components/style/values/specified/length.rs >@@ -1,34 +1,34 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! [Length values][length]. > //! > //! [length]: https://drafts.csswg.org/css-values/#lengths > >+use super::{AllowQuirks, Number, Percentage, ToComputedValue}; > use app_units::Au; > use cssparser::{Parser, Token}; > use euclid::Size2D; > use font_metrics::FontMetricsQueryResult; > use parser::{Parse, ParserContext}; > use std::cmp; > use std::ops::{Add, Mul}; >-use style_traits::{ParseError, SpecifiedValueInfo, StyleParseErrorKind}; > use style_traits::values::specified::AllowedNumericType; >-use super::{AllowQuirks, Number, Percentage, ToComputedValue}; >-use values::{Auto, CSSFloat, Either, Normal}; >+use style_traits::{ParseError, SpecifiedValueInfo, StyleParseErrorKind}; > use values::computed::{self, CSSPixelLength, Context, ExtremumLength}; > use values::generics::NonNegative; > use values::specified::calc::CalcNode; >+use values::{Auto, CSSFloat, Either, Normal}; > >-pub use values::specified::calc::CalcLengthOrPercentage; > pub use super::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; > pub use super::image::{GradientKind, Image}; >+pub use values::specified::calc::CalcLengthOrPercentage; > > /// Number of app units per pixel > pub const AU_PER_PX: CSSFloat = 60.; > /// Number of app units per inch > pub const AU_PER_IN: CSSFloat = AU_PER_PX * 96.; > /// Number of app units per centimeter > pub const AU_PER_CM: CSSFloat = AU_PER_IN / 2.54; > /// Number of app units per millimeter >@@ -85,17 +85,17 @@ pub enum FontBaseSize { > impl FontBaseSize { > /// Calculate the actual size for a given context > pub fn resolve(&self, context: &Context) -> Au { > match *self { > FontBaseSize::Custom(size) => size, > FontBaseSize::CurrentStyle => context.style().get_font().clone_font_size().size(), > FontBaseSize::InheritedStyleButStripEmUnits | FontBaseSize::InheritedStyle => { > context.style().get_parent_font().clone_font_size().size() >- }, >+ } > } > } > } > > impl FontRelativeLength { > /// Computes the font-relative length. > pub fn to_computed_value(&self, context: &Context, base_size: FontBaseSize) -> CSSPixelLength { > use std::f32; >@@ -143,33 +143,33 @@ impl FontRelativeLength { > } > } > > if base_size == FontBaseSize::InheritedStyleButStripEmUnits { > (Au(0), length) > } else { > (reference_font_size, length) > } >- }, >+ } > FontRelativeLength::Ex(length) => { > if context.for_non_inherited_property.is_some() { > context.rule_cache_conditions.borrow_mut().set_uncacheable(); > } > let reference_size = match query_font_metrics(context, reference_font_size) { > FontMetricsQueryResult::Available(metrics) => metrics.x_height, > // https://drafts.csswg.org/css-values/#ex > // > // In the cases where it is impossible or impractical to > // determine the x-height, a value of 0.5em must be > // assumed. > // > FontMetricsQueryResult::NotAvailable => reference_font_size.scale_by(0.5), > }; > (reference_size, length) >- }, >+ } > FontRelativeLength::Ch(length) => { > if context.for_non_inherited_property.is_some() { > context.rule_cache_conditions.borrow_mut().set_uncacheable(); > } > let reference_size = match query_font_metrics(context, reference_font_size) { > FontMetricsQueryResult::Available(metrics) => metrics.zero_advance_measure, > // https://drafts.csswg.org/css-values/#ch > // >@@ -182,34 +182,34 @@ impl FontRelativeLength { > // text-orientation is upright). > // > FontMetricsQueryResult::NotAvailable => { > if context.style().writing_mode.is_vertical() { > reference_font_size > } else { > reference_font_size.scale_by(0.5) > } >- }, >+ } > }; > (reference_size, length) >- }, >+ } > FontRelativeLength::Rem(length) => { > // https://drafts.csswg.org/css-values/#rem: > // > // When specified on the font-size property of the root > // element, the rem units refer to the property's initial > // value. > // > let reference_size = if context.is_root_element || context.in_media_query { > reference_font_size > } else { > context.device().root_font_size() > }; > (reference_size, length) >- }, >+ } > } > } > } > > /// A viewport-relative length. > /// > /// <https://drafts.csswg.org/css-values/#viewport-relative-lengths> > #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, ToCss)] >@@ -231,20 +231,20 @@ pub enum ViewportPercentageLength { > impl ViewportPercentageLength { > /// Computes the given viewport-relative length for the given viewport size. > pub fn to_computed_value(&self, viewport_size: Size2D<Au>) -> CSSPixelLength { > let (factor, length) = match *self { > ViewportPercentageLength::Vw(length) => (length, viewport_size.width), > ViewportPercentageLength::Vh(length) => (length, viewport_size.height), > ViewportPercentageLength::Vmin(length) => { > (length, cmp::min(viewport_size.width, viewport_size.height)) >- }, >+ } > ViewportPercentageLength::Vmax(length) => { > (length, cmp::max(viewport_size.width, viewport_size.height)) >- }, >+ } > }; > > // FIXME: Bug 1396535, we need to fix the extremely small viewport length for transform. > // See bug 989802. We truncate so that adding multiple viewport units > // that add up to 100 does not overflow due to rounding differences > let trunc_scaled = ((length.0 as f64) * factor as f64 / 100.).trunc(); > Au::from_f64_au(trunc_scaled).into() > } >@@ -292,23 +292,23 @@ pub enum AbsoluteLength { > /// An absolute length in pica (pc) > #[css(dimension)] > Pc(CSSFloat), > } > > impl AbsoluteLength { > fn is_zero(&self) -> bool { > match *self { >- AbsoluteLength::Px(v) | >- AbsoluteLength::In(v) | >- AbsoluteLength::Cm(v) | >- AbsoluteLength::Mm(v) | >- AbsoluteLength::Q(v) | >- AbsoluteLength::Pt(v) | >- AbsoluteLength::Pc(v) => v == 0., >+ AbsoluteLength::Px(v) >+ | AbsoluteLength::In(v) >+ | AbsoluteLength::Cm(v) >+ | AbsoluteLength::Mm(v) >+ | AbsoluteLength::Q(v) >+ | AbsoluteLength::Pt(v) >+ | AbsoluteLength::Pc(v) => v == 0., > } > } > > /// Convert this into a pixel value. > #[inline] > pub fn to_px(&self) -> CSSFloat { > use std::f32; > >@@ -561,33 +561,35 @@ impl Length { > ) -> Result<Self, ParseError<'i>> { > // FIXME: remove early returns when lifetimes are non-lexical > { > let location = input.current_source_location(); > let token = input.next()?; > match *token { > Token::Dimension { > value, ref unit, .. >- } if num_context.is_ok(context.parsing_mode, value) => >+ } >+ if num_context.is_ok(context.parsing_mode, value) => > { > return NoCalcLength::parse_dimension(context, value, unit) > .map(Length::NoCalc) > .map_err(|()| location.new_unexpected_token_error(token.clone())) >- }, >+ } > Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { >- if value != 0. && !context.parsing_mode.allows_unitless_lengths() && >- !allow_quirks.allowed(context.quirks_mode) >+ if value != 0. >+ && !context.parsing_mode.allows_unitless_lengths() >+ && !allow_quirks.allowed(context.quirks_mode) > { > return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > return Ok(Length::NoCalc(NoCalcLength::Absolute(AbsoluteLength::Px( > value, > )))); >- }, >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > ref token => return Err(location.new_unexpected_token_error(token.clone())), > } > } > input.parse_nested_block(|input| { > CalcNode::parse_length(context, input, num_context) > .map(|calc| Length::Calc(Box::new(calc))) > }) > } >@@ -748,45 +750,48 @@ impl LengthOrPercentage { > ) -> Result<Self, ParseError<'i>> { > // FIXME: remove early returns when lifetimes are non-lexical > { > let location = input.current_source_location(); > let token = input.next()?; > match *token { > Token::Dimension { > value, ref unit, .. >- } if num_context.is_ok(context.parsing_mode, value) => >+ } >+ if num_context.is_ok(context.parsing_mode, value) => > { > return NoCalcLength::parse_dimension(context, value, unit) > .map(LengthOrPercentage::Length) > .map_err(|()| location.new_unexpected_token_error(token.clone())) >- }, >+ } > Token::Percentage { unit_value, .. } > if num_context.is_ok(context.parsing_mode, unit_value) => > { > return Ok(LengthOrPercentage::Percentage(computed::Percentage( > unit_value, > ))) >- }, >+ } > Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { >- if value != 0. && !context.parsing_mode.allows_unitless_lengths() && >- !allow_quirks.allowed(context.quirks_mode) >+ if value != 0. >+ && !context.parsing_mode.allows_unitless_lengths() >+ && !allow_quirks.allowed(context.quirks_mode) > { > return Err(location.new_unexpected_token_error(token.clone())); > } else { > return Ok(LengthOrPercentage::Length(NoCalcLength::from_px(value))); > } >- }, >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > _ => return Err(location.new_unexpected_token_error(token.clone())), > } > } > >- let calc = input >- .parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?; >+ let calc = input.parse_nested_block(|i| { >+ CalcNode::parse_length_or_percentage(context, i, num_context) >+ })?; > Ok(LengthOrPercentage::Calc(Box::new(calc))) > } > > /// Parse a non-negative length. > #[inline] > pub fn parse_non_negative<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -866,49 +871,52 @@ impl LengthOrPercentageOrAuto { > ) -> Result<Self, ParseError<'i>> { > // FIXME: remove early returns when lifetimes are non-lexical > { > let location = input.current_source_location(); > let token = input.next()?; > match *token { > Token::Dimension { > value, ref unit, .. >- } if num_context.is_ok(context.parsing_mode, value) => >+ } >+ if num_context.is_ok(context.parsing_mode, value) => > { > return NoCalcLength::parse_dimension(context, value, unit) > .map(LengthOrPercentageOrAuto::Length) > .map_err(|()| location.new_unexpected_token_error(token.clone())) >- }, >+ } > Token::Percentage { unit_value, .. } > if num_context.is_ok(context.parsing_mode, unit_value) => > { > return Ok(LengthOrPercentageOrAuto::Percentage(computed::Percentage( > unit_value, > ))) >- }, >+ } > Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { >- if value != 0. && !context.parsing_mode.allows_unitless_lengths() && >- !allow_quirks.allowed(context.quirks_mode) >+ if value != 0. >+ && !context.parsing_mode.allows_unitless_lengths() >+ && !allow_quirks.allowed(context.quirks_mode) > { > return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > return Ok(LengthOrPercentageOrAuto::Length(NoCalcLength::Absolute( > AbsoluteLength::Px(value), > ))); >- }, >+ } > Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { > return Ok(LengthOrPercentageOrAuto::Auto) >- }, >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > _ => return Err(location.new_unexpected_token_error(token.clone())), > } > } > >- let calc = input >- .parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?; >+ let calc = input.parse_nested_block(|i| { >+ CalcNode::parse_length_or_percentage(context, i, num_context) >+ })?; > Ok(LengthOrPercentageOrAuto::Calc(Box::new(calc))) > } > > /// Parse a non-negative length, percentage, or auto. > #[inline] > pub fn parse_non_negative<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -993,18 +1001,17 @@ impl NonNegativeLengthOrPercentageOrAuto { > > impl Parse for NonNegativeLengthOrPercentageOrAuto { > #[inline] > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > Ok(NonNegative(LengthOrPercentageOrAuto::parse_non_negative( >- context, >- input, >+ context, input, > )?)) > } > } > > /// Either a `<length>`, a `<percentage>`, or the `none` keyword. > #[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > #[allow(missing_docs)] > pub enum LengthOrPercentageOrNone { >@@ -1023,49 +1030,52 @@ impl LengthOrPercentageOrNone { > ) -> Result<Self, ParseError<'i>> { > // FIXME: remove early returns when lifetimes are non-lexical > { > let location = input.current_source_location(); > let token = input.next()?; > match *token { > Token::Dimension { > value, ref unit, .. >- } if num_context.is_ok(context.parsing_mode, value) => >+ } >+ if num_context.is_ok(context.parsing_mode, value) => > { > return NoCalcLength::parse_dimension(context, value, unit) > .map(LengthOrPercentageOrNone::Length) > .map_err(|()| location.new_unexpected_token_error(token.clone())) >- }, >+ } > Token::Percentage { unit_value, .. } > if num_context.is_ok(context.parsing_mode, unit_value) => > { > return Ok(LengthOrPercentageOrNone::Percentage(computed::Percentage( > unit_value, > ))) >- }, >+ } > Token::Number { value, .. } if num_context.is_ok(context.parsing_mode, value) => { >- if value != 0. && !context.parsing_mode.allows_unitless_lengths() && >- !allow_quirks.allowed(context.quirks_mode) >+ if value != 0. >+ && !context.parsing_mode.allows_unitless_lengths() >+ && !allow_quirks.allowed(context.quirks_mode) > { > return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > return Ok(LengthOrPercentageOrNone::Length(NoCalcLength::Absolute( > AbsoluteLength::Px(value), > ))); >- }, >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > Token::Ident(ref value) if value.eq_ignore_ascii_case("none") => { > return Ok(LengthOrPercentageOrNone::None) >- }, >+ } > _ => return Err(location.new_unexpected_token_error(token.clone())), > } > } > >- let calc = input >- .parse_nested_block(|i| CalcNode::parse_length_or_percentage(context, i, num_context))?; >+ let calc = input.parse_nested_block(|i| { >+ CalcNode::parse_length_or_percentage(context, i, num_context) >+ })?; > Ok(LengthOrPercentageOrNone::Calc(Box::new(calc))) > } > > /// Parse a non-negative LengthOrPercentageOrNone. > #[inline] > pub fn parse_non_negative<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >diff --git a/servo/components/style/values/specified/list.rs b/servo/components/style/values/specified/list.rs >index ae61bb1ae9cb..c63d7d85018f 100644 >--- a/servo/components/style/values/specified/list.rs >+++ b/servo/components/style/values/specified/list.rs >@@ -4,24 +4,23 @@ > > //! `list` specified values. > > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > #[cfg(feature = "gecko")] >-use values::CustomIdent; >-#[cfg(feature = "gecko")] > use values::generics::CounterStyleOrNone; >+#[cfg(feature = "gecko")] >+use values::CustomIdent; > > /// Specified and computed `list-style-type` property. > #[cfg(feature = "gecko")] >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub enum ListStyleType { > /// <counter-style> | none > CounterStyle(CounterStyleOrNone), > /// <string> > String(String), > } > > #[cfg(feature = "gecko")] >@@ -74,33 +73,32 @@ impl Parse for ListStyleType { > } > } > > /// Specified and computed `quote` property. > /// > /// FIXME(emilio): It's a shame that this allocates all the time it's computed, > /// probably should just be refcounted. > /// FIXME This can probably derive ToCss. >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct Quotes(#[css(if_empty = "none")] pub Box<[(Box<str>, Box<str>)]>); > > impl ToCss for Quotes { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > let mut iter = self.0.iter(); > > match iter.next() { > Some(&(ref l, ref r)) => { > l.to_css(dest)?; > dest.write_char(' ')?; > r.to_css(dest)?; >- }, >+ } > None => return dest.write_str("none"), > } > > for &(ref l, ref r) in iter { > dest.write_char(' ')?; > l.to_css(dest)?; > dest.write_char(' ')?; > r.to_css(dest)?; >diff --git a/servo/components/style/values/specified/mod.rs b/servo/components/style/values/specified/mod.rs >index 2da4c7e93d3e..ccb7440b42ff 100644 >--- a/servo/components/style/values/specified/mod.rs >+++ b/servo/components/style/values/specified/mod.rs >@@ -1,87 +1,91 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified values. > //! > //! TODO(emilio): Enhance docs. > >-use {Atom, Namespace, Prefix}; >+use super::computed::{Context, ToComputedValue}; >+use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; >+use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; >+use super::generics::{GreaterThanOrEqualToOne, NonNegative}; >+use super::{Auto, CSSFloat, CSSInteger, Either}; > use context::QuirksMode; > use cssparser::{Parser, Token}; > use num_traits::One; > use parser::{Parse, ParserContext}; > use std::f32; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use style_traits::values::specified::AllowedNumericType; >-use super::{Auto, CSSFloat, CSSInteger, Either}; >-use super::computed::{Context, ToComputedValue}; >-use super::generics::{GreaterThanOrEqualToOne, NonNegative}; >-use super::generics::grid::{GridLine as GenericGridLine, TrackBreadth as GenericTrackBreadth}; >-use super::generics::grid::{TrackList as GenericTrackList, TrackSize as GenericTrackSize}; >+use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use values::serialize_atom_identifier; > use values::specified::calc::CalcNode; >+use {Atom, Namespace, Prefix}; > >-pub use self::angle::Angle; > #[cfg(feature = "gecko")] > pub use self::align::{AlignContent, AlignItems, AlignSelf, ContentDistribution}; > #[cfg(feature = "gecko")] > pub use self::align::{JustifyContent, JustifyItems, JustifySelf, SelfAlignment}; >+pub use self::angle::Angle; > pub use self::background::{BackgroundRepeat, BackgroundSize}; > pub use self::border::{BorderCornerRadius, BorderImageSlice, BorderImageWidth}; > pub use self::border::{BorderImageRepeat, BorderImageSideWidth}; > pub use self::border::{BorderRadius, BorderSideWidth, BorderSpacing}; >-pub use self::column::ColumnCount; >-pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight}; >-pub use self::font::{FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings}; >-pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; >-pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; > pub use self::box_::{AnimationIterationCount, AnimationName, Contain, Display}; > pub use self::box_::{Appearance, Clear, Float}; > pub use self::box_::{OverflowClipBox, OverscrollBehavior, Perspective, Resize}; > pub use self::box_::{ScrollSnapType, TouchAction, TransitionProperty, VerticalAlign, WillChange}; > pub use self::color::{Color, ColorPropertyValue, RGBAColor}; >+pub use self::column::ColumnCount; > pub use self::counters::{Content, ContentItem, CounterIncrement, CounterReset}; > pub use self::effects::{BoxShadow, Filter, SimpleShadow}; > pub use self::flex::FlexBasis; >+pub use self::font::{ >+ FontFamily, FontLanguageOverride, FontStyle, FontVariantEastAsian, FontVariationSettings, >+}; >+pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric}; >+pub use self::font::{ >+ FontSize, FontSizeAdjust, FontStretch, FontSynthesis, FontVariantAlternates, FontWeight, >+}; >+pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom}; > #[cfg(feature = "gecko")] > pub use self::gecko::ScrollSnapPoint; > pub use self::image::{ColorStop, EndingShape as GradientEndingShape, Gradient}; > pub use self::image::{GradientItem, GradientKind, Image, ImageLayer, MozImageRect}; > pub use self::length::{AbsoluteLength, CalcLengthOrPercentage, CharacterWidth}; > pub use self::length::{FontRelativeLength, Length, LengthOrNumber}; > pub use self::length::{LengthOrPercentage, LengthOrPercentageOrAuto}; > pub use self::length::{LengthOrPercentageOrNone, MaxLength, MozLength}; > pub use self::length::{NoCalcLength, ViewportPercentageLength}; > pub use self::length::{NonNegativeLengthOrPercentage, NonNegativeLengthOrPercentageOrAuto}; >-pub use self::list::Quotes; > #[cfg(feature = "gecko")] > pub use self::list::ListStyleType; >+pub use self::list::Quotes; > pub use self::outline::OutlineStyle; >-pub use self::rect::LengthOrNumberRect; >-pub use self::resolution::Resolution; > pub use self::percentage::Percentage; > pub use self::position::{GridAutoFlow, GridTemplateAreas, Position}; > pub use self::position::{PositionComponent, ZIndex}; >+pub use self::rect::LengthOrNumberRect; >+pub use self::resolution::Resolution; >+pub use self::svg::MozContextProperties; > pub use self::svg::{SVGLength, SVGOpacity, SVGPaint, SVGPaintKind}; > pub use self::svg::{SVGPaintOrder, SVGStrokeDashArray, SVGWidth}; >-pub use self::svg::MozContextProperties; > pub use self::table::XSpan; > pub use self::text::{InitialLetter, LetterSpacing, LineHeight, MozTabSize, TextAlign}; >-pub use self::text::{TextEmphasisPosition, TextEmphasisStyle}; > pub use self::text::{TextAlignKeyword, TextDecorationLine, TextOverflow, WordSpacing}; >+pub use self::text::{TextEmphasisPosition, TextEmphasisStyle}; > pub use self::time::Time; > pub use self::transform::{Rotate, Scale, TimingFunction, Transform}; > pub use self::transform::{TransformOrigin, TransformStyle, Translate}; >-pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon}; > #[cfg(feature = "gecko")] > pub use self::ui::CursorImage; >+pub use self::ui::{ColorOrAuto, Cursor, MozForceBrokenImageIcon}; > pub use super::generics::grid::GridTemplateComponent as GenericGridTemplateComponent; > > #[cfg(feature = "gecko")] > pub mod align; > pub mod angle; > pub mod background; > pub mod basic_shape; > pub mod border; >@@ -123,18 +127,18 @@ fn parse_number_with_clamping_mode<'i, 't>( > let location = input.current_source_location(); > // FIXME: remove early returns when lifetimes are non-lexical > match *input.next()? { > Token::Number { value, .. } if clamping_mode.is_ok(context.parsing_mode, value) => { > return Ok(Number { > value: value.min(f32::MAX).max(f32::MIN), > calc_clamping_mode: None, > }) >- }, >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ } >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > ref t => return Err(location.new_unexpected_token_error(t.clone())), > } > > let result = input.parse_nested_block(|i| CalcNode::parse_number(context, i))?; > > Ok(Number { > value: result.min(f32::MAX).max(f32::MIN), > calc_clamping_mode: Some(clamping_mode), >@@ -142,18 +146,30 @@ fn parse_number_with_clamping_mode<'i, 't>( > } > > // The integer values here correspond to the border conflict resolution rules in CSS 2.1 § > // 17.6.2.1. Higher values override lower values. > // > // FIXME(emilio): Should move to border.rs > #[allow(missing_docs)] > #[cfg_attr(feature = "servo", derive(Deserialize, Serialize))] >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord, Parse, PartialEq, >- PartialOrd, SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Ord, >+ Parse, >+ PartialEq, >+ PartialOrd, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum BorderStyle { > None = -1, > Solid = 6, > Double = 7, > Dotted = 4, > Dashed = 5, > Hidden = -2, > Groove = 1, >@@ -321,18 +337,17 @@ impl Parse for GreaterThanOrEqualToOneNumber { > } > > /// <number> | <percentage> > /// > /// Accepts only non-negative numbers. > /// > /// FIXME(emilio): Should probably use Either. > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum NumberOrPercentage { > Percentage(Percentage), > Number(Number), > } > > impl NumberOrPercentage { > fn parse_with_clamping_mode<'i, 't>( > context: &ParserContext, >@@ -360,18 +375,17 @@ impl Parse for NumberOrPercentage { > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > Self::parse_with_clamping_mode(context, input, AllowedNumericType::All) > } > } > > #[allow(missing_docs)] >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, >- SpecifiedValueInfo, ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, PartialOrd, SpecifiedValueInfo, ToCss)] > pub struct Opacity(Number); > > impl Parse for Opacity { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > Number::parse(context, input).map(Opacity) >@@ -454,17 +468,17 @@ impl Parse for Integer { > ) -> Result<Self, ParseError<'i>> { > let location = input.current_source_location(); > > // FIXME: remove early returns when lifetimes are non-lexical > match *input.next()? { > Token::Number { > int_value: Some(v), .. > } => return Ok(Integer::new(v)), >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > ref t => return Err(location.new_unexpected_token_error(t.clone())), > } > > let result = input.parse_nested_block(|i| CalcNode::parse_integer(context, i))?; > > Ok(Integer::from_calc(result)) > } > } >@@ -621,23 +635,26 @@ impl ToCss for ClipRect { > > impl ToComputedValue for ClipRect { > type ComputedValue = super::computed::ClipRect; > > #[inline] > fn to_computed_value(&self, context: &Context) -> super::computed::ClipRect { > super::computed::ClipRect { > top: self.top.as_ref().map(|top| top.to_computed_value(context)), >- right: self.right >+ right: self >+ .right > .as_ref() > .map(|right| right.to_computed_value(context)), >- bottom: self.bottom >+ bottom: self >+ .bottom > .as_ref() > .map(|bottom| bottom.to_computed_value(context)), >- left: self.left >+ left: self >+ .left > .as_ref() > .map(|left| left.to_computed_value(context)), > } > } > > #[inline] > fn from_computed_value(computed: &super::computed::ClipRect) -> Self { > ClipRect { >@@ -751,18 +768,17 @@ impl AllowQuirks { > pub fn allowed(self, quirks_mode: QuirksMode) -> bool { > self == AllowQuirks::Yes && quirks_mode == QuirksMode::Quirks > } > } > > /// An attr(...) rule > /// > /// `[namespace? `|`]? ident` >-#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > #[css(function)] > pub struct Attr { > /// Optional namespace prefix and URL. > pub namespace: Option<(Prefix, Namespace)>, > /// Attribute name > pub attribute: Atom, > } > >@@ -805,30 +821,33 @@ impl Attr { > Token::Ident(ref second) => second, > ref t => return Err(location.new_unexpected_token_error(t.clone())), > }; > > let prefix_and_ns = if let Some(ns) = first { > let prefix = Prefix::from(ns.as_ref()); > let ns = match get_namespace_for_prefix(&prefix, context) { > Some(ns) => ns, >- None => return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError)), >+ None => { >+ return Err(location >+ .new_custom_error(StyleParseErrorKind::UnspecifiedError)) >+ } > }; > Some((prefix, ns)) > } else { > None > }; > return Ok(Attr { > namespace: prefix_and_ns, > attribute: Atom::from(second_token.as_ref()), > }); >- }, >+ } > // In the case of attr(foobar ) we don't want to error out > // because of the trailing whitespace >- Token::WhiteSpace(..) => {}, >+ Token::WhiteSpace(..) => {} > ref t => return Err(input.new_unexpected_token_error(t.clone())), > } > } > > if let Some(first) = first { > Ok(Attr { > namespace: None, > attribute: Atom::from(first.as_ref()), >diff --git a/servo/components/style/values/specified/outline.rs b/servo/components/style/values/specified/outline.rs >index c3357f87ec22..afe74dc39f39 100644 >--- a/servo/components/style/values/specified/outline.rs >+++ b/servo/components/style/values/specified/outline.rs >@@ -5,18 +5,29 @@ > //! Specified values for outline properties > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use style_traits::ParseError; > use values::specified::BorderStyle; > >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Ord, PartialEq, PartialOrd, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Ord, >+ PartialEq, >+ PartialOrd, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > /// <https://drafts.csswg.org/css-ui/#propdef-outline-style> > pub enum OutlineStyle { > /// auto > Auto, > /// <border-style> > Other(BorderStyle), > } > >diff --git a/servo/components/style/values/specified/percentage.rs b/servo/components/style/values/specified/percentage.rs >index 9f8fb1bfbf5b..33a99868941e 100644 >--- a/servo/components/style/values/specified/percentage.rs >+++ b/servo/components/style/values/specified/percentage.rs >@@ -2,22 +2,22 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified percentages. > > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss}; > use style_traits::values::specified::AllowedNumericType; >-use values::{serialize_percentage, CSSFloat}; >-use values::computed::{Context, ToComputedValue}; >+use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, ToCss}; > use values::computed::percentage::Percentage as ComputedPercentage; >+use values::computed::{Context, ToComputedValue}; > use values::specified::calc::CalcNode; >+use values::{serialize_percentage, CSSFloat}; > > /// A percentage value. > #[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)] > pub struct Percentage { > /// The percentage value as a float. > /// > /// [0 .. 100%] maps to [0.0 .. 1.0] > value: CSSFloat, >@@ -98,17 +98,17 @@ impl Percentage { > let location = input.current_source_location(); > // FIXME: remove early returns when lifetimes are non-lexical > match *input.next()? { > Token::Percentage { unit_value, .. } > if num_context.is_ok(context.parsing_mode, unit_value) => > { > return Ok(Percentage::new(unit_value)); > } >- Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {}, >+ Token::Function(ref name) if name.eq_ignore_ascii_case("calc") => {} > ref t => return Err(location.new_unexpected_token_error(t.clone())), > } > > let result = input.parse_nested_block(|i| CalcNode::parse_percentage(context, i))?; > > // TODO(emilio): -moz-image-rect is the only thing that uses > // the clamping mode... I guess we could disallow it... > Ok(Percentage { >diff --git a/servo/components/style/values/specified/position.rs b/servo/components/style/values/specified/position.rs >index fcfa07ae1d86..156f901d4ab5 100644 >--- a/servo/components/style/values/specified/position.rs >+++ b/servo/components/style/values/specified/position.rs >@@ -11,23 +11,23 @@ use cssparser::Parser; > use hash::FxHashMap; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use servo_arc::Arc; > use std::fmt::{self, Write}; > use std::ops::Range; > use str::HTML_SPACE_CHARACTERS; > use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; >-use values::{Either, None_}; > use values::computed::{CalcLengthOrPercentage, LengthOrPercentage as ComputedLengthOrPercentage}; > use values::computed::{Context, Percentage, ToComputedValue}; > use values::generics::position::Position as GenericPosition; > use values::generics::position::ZIndex as GenericZIndex; >-use values::specified::{AllowQuirks, Integer, LengthOrPercentage}; > use values::specified::transform::OriginComponent; >+use values::specified::{AllowQuirks, Integer, LengthOrPercentage}; >+use values::{Either, None_}; > > /// The specified value of a CSS `<position>` > pub type Position = GenericPosition<HorizontalPosition, VerticalPosition>; > > /// The specified value of a horizontal position. > pub type HorizontalPosition = PositionComponent<X>; > > /// The specified value of a vertical position. >@@ -40,27 +40,49 @@ pub enum PositionComponent<S> { > Center, > /// `<lop>` > Length(LengthOrPercentage), > /// `<side> <lop>?` > Side(S, Option<LengthOrPercentage>), > } > > /// A keyword for the X direction. >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ Hash, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > #[allow(missing_docs)] > pub enum X { > Left, > Right, > } > > /// A keyword for the Y direction. >-#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ Hash, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > #[allow(missing_docs)] > pub enum Y { > Top, > Bottom, > } > > impl Parse for Position { > fn parse<'i, 't>( >@@ -85,17 +107,17 @@ impl Position { > { > return Ok(Self::new(x_pos, y_pos)); > } > let x_pos = input > .try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) > .unwrap_or(x_pos); > let y_pos = PositionComponent::Center; > return Ok(Self::new(x_pos, y_pos)); >- }, >+ } > Ok(PositionComponent::Side(x_keyword, lop)) => { > if input.try(|i| i.expect_ident_matching("center")).is_ok() { > let x_pos = PositionComponent::Side(x_keyword, lop); > let y_pos = PositionComponent::Center; > return Ok(Self::new(x_pos, y_pos)); > } > if let Ok(y_keyword) = input.try(Y::parse) { > let y_lop = input >@@ -103,40 +125,42 @@ impl Position { > .ok(); > let x_pos = PositionComponent::Side(x_keyword, lop); > let y_pos = PositionComponent::Side(y_keyword, y_lop); > return Ok(Self::new(x_pos, y_pos)); > } > let x_pos = PositionComponent::Side(x_keyword, None); > let y_pos = lop.map_or(PositionComponent::Center, PositionComponent::Length); > return Ok(Self::new(x_pos, y_pos)); >- }, >+ } > Ok(x_pos @ PositionComponent::Length(_)) => { > if let Ok(y_keyword) = input.try(Y::parse) { > let y_pos = PositionComponent::Side(y_keyword, None); > return Ok(Self::new(x_pos, y_pos)); > } > if let Ok(y_lop) = > input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) > { > let y_pos = PositionComponent::Length(y_lop); > return Ok(Self::new(x_pos, y_pos)); > } > let y_pos = PositionComponent::Center; > let _ = input.try(|i| i.expect_ident_matching("center")); > return Ok(Self::new(x_pos, y_pos)); >- }, >- Err(_) => {}, >+ } >+ Err(_) => {} > } > let y_keyword = Y::parse(input)?; > let lop_and_x_pos: Result<_, ParseError> = input.try(|i| { >- let y_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) >+ let y_lop = i >+ .try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) > .ok(); > if let Ok(x_keyword) = i.try(X::parse) { >- let x_lop = i.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) >+ let x_lop = i >+ .try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) > .ok(); > let x_pos = PositionComponent::Side(x_keyword, x_lop); > return Ok((y_lop, x_pos)); > }; > i.expect_ident_matching("center")?; > let x_pos = PositionComponent::Center; > Ok((y_lop, x_pos)) > }); >@@ -164,31 +188,31 @@ impl ToCss for Position { > match (&self.horizontal, &self.vertical) { > ( > x_pos @ &PositionComponent::Side(_, Some(_)), > &PositionComponent::Length(ref y_lop), > ) => { > x_pos.to_css(dest)?; > dest.write_str(" top ")?; > y_lop.to_css(dest) >- }, >+ } > ( > &PositionComponent::Length(ref x_lop), > y_pos @ &PositionComponent::Side(_, Some(_)), > ) => { > dest.write_str("left ")?; > x_lop.to_css(dest)?; > dest.write_str(" ")?; > y_pos.to_css(dest) >- }, >+ } > (x_pos, y_pos) => { > x_pos.to_css(dest)?; > dest.write_str(" ")?; > y_pos.to_css(dest) >- }, >+ } > } > } > } > > impl<S: Parse> Parse for PositionComponent<S> { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -229,34 +253,34 @@ impl<S: Side> ToComputedValue for PositionComponent<S> { > type ComputedValue = ComputedLengthOrPercentage; > > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > PositionComponent::Center => ComputedLengthOrPercentage::Percentage(Percentage(0.5)), > PositionComponent::Side(ref keyword, None) => { > let p = Percentage(if keyword.is_start() { 0. } else { 1. }); > ComputedLengthOrPercentage::Percentage(p) >- }, >+ } > PositionComponent::Side(ref keyword, Some(ref length)) if !keyword.is_start() => { > match length.to_computed_value(context) { > ComputedLengthOrPercentage::Length(length) => ComputedLengthOrPercentage::Calc( > CalcLengthOrPercentage::new(-length, Some(Percentage::hundred())), > ), > ComputedLengthOrPercentage::Percentage(p) => { > ComputedLengthOrPercentage::Percentage(Percentage(1.0 - p.0)) >- }, >+ } > ComputedLengthOrPercentage::Calc(calc) => { > let p = Percentage(1. - calc.percentage.map_or(0., |p| p.0)); > let l = -calc.unclamped_length(); > ComputedLengthOrPercentage::Calc(CalcLengthOrPercentage::new(l, Some(p))) >- }, >+ } > } >- }, >- PositionComponent::Side(_, Some(ref length)) | >- PositionComponent::Length(ref length) => length.to_computed_value(context), >+ } >+ PositionComponent::Side(_, Some(ref length)) >+ | PositionComponent::Length(ref length) => length.to_computed_value(context), > } > } > > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > PositionComponent::Length(ToComputedValue::from_computed_value(computed)) > } > } > >@@ -338,47 +362,47 @@ impl LegacyPosition { > if let Ok(y_pos) = input.try(|i| OriginComponent::parse(context, i)) { > return Ok(Self::new(x_pos, y_pos)); > } > let x_pos = input > .try(|i| OriginComponent::parse(context, i)) > .unwrap_or(x_pos); > let y_pos = OriginComponent::Center; > return Ok(Self::new(x_pos, y_pos)); >- }, >+ } > Ok(OriginComponent::Side(x_keyword)) => { > if let Ok(y_keyword) = input.try(Y::parse) { > let x_pos = OriginComponent::Side(x_keyword); > let y_pos = OriginComponent::Side(y_keyword); > return Ok(Self::new(x_pos, y_pos)); > } > let x_pos = OriginComponent::Side(x_keyword); > if let Ok(y_lop) = > input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) > { > return Ok(Self::new(x_pos, OriginComponent::Length(y_lop))); > } > let _ = input.try(|i| i.expect_ident_matching("center")); > return Ok(Self::new(x_pos, OriginComponent::Center)); >- }, >+ } > Ok(x_pos @ OriginComponent::Length(_)) => { > if let Ok(y_keyword) = input.try(Y::parse) { > let y_pos = OriginComponent::Side(y_keyword); > return Ok(Self::new(x_pos, y_pos)); > } > if let Ok(y_lop) = > input.try(|i| LengthOrPercentage::parse_quirky(context, i, allow_quirks)) > { > let y_pos = OriginComponent::Length(y_lop); > return Ok(Self::new(x_pos, y_pos)); > } > let _ = input.try(|i| i.expect_ident_matching("center")); > return Ok(Self::new(x_pos, OriginComponent::Center)); >- }, >- Err(_) => {}, >+ } >+ Err(_) => {} > } > let y_keyword = Y::parse(input)?; > let x_pos: Result<_, ParseError> = input.try(|i| { > if let Ok(x_keyword) = i.try(X::parse) { > let x_pos = OriginComponent::Side(x_keyword); > return Ok(x_pos); > } > i.expect_ident_matching("center")?; >@@ -406,30 +430,32 @@ impl ToCss for LegacyPosition { > W: Write, > { > self.horizontal.to_css(dest)?; > dest.write_str(" ")?; > self.vertical.to_css(dest) > } > } > >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > /// Auto-placement algorithm Option > pub enum AutoFlow { > /// The auto-placement algorithm places items by filling each row in turn, > /// adding new rows as necessary. > Row, > /// The auto-placement algorithm places items by filling each column in turn, > /// adding new columns as necessary. > Column, > } > >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > /// Controls how the auto-placement algorithm works > /// specifying exactly how auto-placed items get flowed into the grid > pub struct GridAutoFlow { > /// Specifiy how auto-placement algorithm fills each `row` or `column` in turn > pub autoflow: AutoFlow, > /// Specify use `dense` packing algorithm or not > #[css(represents_keyword)] > pub dense: bool, >@@ -625,18 +651,17 @@ impl Parse for TemplateAreas { > } > > TemplateAreas::from_vec(strings) > .map_err(|()| input.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > > /// Arc type for `Arc<TemplateAreas>` >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct TemplateAreasArc(#[ignore_malloc_size_of = "Arc"] pub Arc<TemplateAreas>); > > impl Parse for TemplateAreasArc { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let parsed = TemplateAreas::parse(context, input)?; >@@ -680,18 +705,22 @@ impl<'a> Iterator for TemplateAreasTokenizer<'a> { > let token_len = rest.find(|c| !is_name_code_point(c)).unwrap_or(rest.len()); > let token = &rest[..token_len]; > self.0 = &rest[token_len..]; > Some(Ok(Some(token))) > } > } > > fn is_name_code_point(c: char) -> bool { >- c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c >= '\u{80}' || c == '_' || >- c >= '0' && c <= '9' || c == '-' >+ c >= 'A' && c <= 'Z' >+ || c >= 'a' && c <= 'z' >+ || c >= '\u{80}' >+ || c == '_' >+ || c >= '0' && c <= '9' >+ || c == '-' > } > > /// This property specifies named grid areas. > /// The syntax of this property also provides a visualization of > /// the structure of the grid, making the overall layout of > /// the grid container easier to understand. > pub type GridTemplateAreas = Either<TemplateAreasArc, None_>; > >diff --git a/servo/components/style/values/specified/resolution.rs b/servo/components/style/values/specified/resolution.rs >index 77a269c251b7..0878c7762728 100644 >--- a/servo/components/style/values/specified/resolution.rs >+++ b/servo/components/style/values/specified/resolution.rs >@@ -27,28 +27,26 @@ pub enum Resolution { > #[css(dimension)] > Dpcm(CSSFloat), > } > > impl Resolution { > /// Convert this resolution value to dppx units. > pub fn to_dppx(&self) -> CSSFloat { > match *self { >- Resolution::X(f) | >- Resolution::Dppx(f) => f, >+ Resolution::X(f) | Resolution::Dppx(f) => f, > _ => self.to_dpi() / 96.0, > } > } > > /// Convert this resolution value to dpi units. > pub fn to_dpi(&self) -> CSSFloat { > match *self { > Resolution::Dpi(f) => f, >- Resolution::X(f) | >- Resolution::Dppx(f) => f * 96.0, >+ Resolution::X(f) | Resolution::Dppx(f) => f * 96.0, > Resolution::Dpcm(f) => f * 2.54, > } > } > } > > impl Parse for Resolution { > fn parse<'i, 't>( > _: &ParserContext, >diff --git a/servo/components/style/values/specified/source_size_list.rs b/servo/components/style/values/specified/source_size_list.rs >index 33078c064840..86a1f84ef56e 100644 >--- a/servo/components/style/values/specified/source_size_list.rs >+++ b/servo/components/style/values/specified/source_size_list.rs >@@ -56,17 +56,18 @@ impl SourceSizeList { > > /// Set content of `value`, which can be used as fall-back during evaluate. > pub fn set_fallback_value(&mut self, width: Option<Length>) { > self.value = width; > } > > /// Evaluate this <source-size-list> to get the final viewport length. > pub fn evaluate(&self, device: &Device, quirks_mode: QuirksMode) -> Au { >- let matching_source_size = self.source_sizes >+ let matching_source_size = self >+ .source_sizes > .iter() > .find(|source_size| source_size.condition.matches(device, quirks_mode)); > > computed::Context::for_media_query_evaluation(device, quirks_mode, |context| { > match matching_source_size { > Some(source_size) => source_size.value.to_computed_value(context), > None => match self.value { > Some(ref v) => v.to_computed_value(context), >@@ -111,25 +112,25 @@ impl SourceSizeList { > }); > > match result { > Ok(SourceSizeOrLength::Length(value)) => { > return Self { > source_sizes, > value: Some(value), > } >- }, >+ } > Ok(SourceSizeOrLength::SourceSize(source_size)) => { > source_sizes.push(source_size); >- }, >- Err(..) => {}, >+ } >+ Err(..) => {} > } > > match input.next() { >- Ok(&Token::Comma) => {}, >+ Ok(&Token::Comma) => {} > Err(..) => break, > _ => unreachable!(), > } > } > > SourceSizeList { > source_sizes, > value: None, >diff --git a/servo/components/style/values/specified/svg.rs b/servo/components/style/values/specified/svg.rs >index e55442d7da82..9e59231c78de 100644 >--- a/servo/components/style/values/specified/svg.rs >+++ b/servo/components/style/values/specified/svg.rs >@@ -4,22 +4,22 @@ > > //! Specified types for SVG properties. > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; > use style_traits::{CommaWithSpace, CssWriter, ParseError, Separator}; > use style_traits::{StyleParseErrorKind, ToCss}; >-use values::CustomIdent; > use values::generics::svg as generic; >-use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber}; >-use values::specified::{Number, Opacity}; > use values::specified::color::Color; > use values::specified::url::SpecifiedUrl; >+use values::specified::{LengthOrPercentage, NonNegativeLengthOrPercentage, NonNegativeNumber}; >+use values::specified::{Number, Opacity}; >+use values::CustomIdent; > > /// Specified SVG Paint value > pub type SVGPaint = generic::SVGPaint<Color, SpecifiedUrl>; > > /// Specified SVG Paint Kind value > pub type SVGPaintKind = generic::SVGPaintKind<Color, SpecifiedUrl>; > > #[cfg(feature = "gecko")] >@@ -168,18 +168,17 @@ const PAINT_ORDER_MASK: u8 = 0b11; > /// > /// Each pair can be set to FILL, STROKE, or MARKERS > /// Lowest significant bit pairs are highest priority. > /// `normal` is the empty bitfield. The three pairs are > /// never zero in any case other than `normal`. > /// > /// Higher priority values, i.e. the values specified first, > /// will be painted first (and may be covered by paintings of lower priority) >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct SVGPaintOrder(pub u8); > > impl SVGPaintOrder { > /// Get default `paint-order` with `0` > pub fn normal() -> Self { > SVGPaintOrder(0) > } > >@@ -219,17 +218,17 @@ impl Parse for SVGPaintOrder { > if (seen & (1 << val as u8)) != 0 { > // don't parse the same ident twice > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } > > value |= (val as u8) << (pos * PAINT_ORDER_SHIFT); > seen |= 1 << (val as u8); > pos += 1; >- }, >+ } > Err(_) => break, > } > } > > if value == 0 { > // Couldn't find any keyword > return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } >@@ -276,18 +275,17 @@ impl ToCss for SVGPaintOrder { > self.order_at(pos).to_css(dest)?; > } > Ok(()) > } > } > > /// Specified MozContextProperties value. > /// Nonstandard (https://developer.mozilla.org/en-US/docs/Web/CSS/-moz-context-properties) >-#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive(Clone, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss)] > pub struct MozContextProperties(pub CustomIdent); > > impl Parse for MozContextProperties { > fn parse<'i, 't>( > _context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<MozContextProperties, ParseError<'i>> { > let location = input.current_source_location(); >diff --git a/servo/components/style/values/specified/table.rs b/servo/components/style/values/specified/table.rs >index 085c9adc9d87..0dd0755f95a1 100644 >--- a/servo/components/style/values/specified/table.rs >+++ b/servo/components/style/values/specified/table.rs >@@ -3,18 +3,19 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified types for table properties. > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use style_traits::{ParseError, StyleParseErrorKind}; > >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > /// span. for `<col span>` pres attr > pub struct XSpan(#[css(skip)] pub i32); > > impl Parse for XSpan { > // never parse it, only set via presentation attribute > fn parse<'i, 't>( > _: &ParserContext, > input: &mut Parser<'i, 't>, >diff --git a/servo/components/style/values/specified/text.rs b/servo/components/style/values/specified/text.rs >index ae01040e45f8..afdc1e97d359 100644 >--- a/servo/components/style/values/specified/text.rs >+++ b/servo/components/style/values/specified/text.rs >@@ -4,32 +4,32 @@ > > //! Specified types for text properties. > > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use properties::longhands::writing_mode::computed_value::T as SpecifiedWritingMode; > use selectors::parser::SelectorParseErrorKind; > use std::fmt::{self, Write}; >+use style_traits::values::SequenceWriter; > use style_traits::{CssWriter, KeywordsCollectFn, ParseError}; > use style_traits::{SpecifiedValueInfo, StyleParseErrorKind, ToCss}; >-use style_traits::values::SequenceWriter; > use unicode_segmentation::UnicodeSegmentation; >-use values::computed::{Context, ToComputedValue}; > use values::computed::text::LineHeight as ComputedLineHeight; > use values::computed::text::TextEmphasisKeywordValue as ComputedTextEmphasisKeywordValue; > use values::computed::text::TextEmphasisStyle as ComputedTextEmphasisStyle; > use values::computed::text::TextOverflow as ComputedTextOverflow; >+use values::computed::{Context, ToComputedValue}; > use values::generics::text::InitialLetter as GenericInitialLetter; > use values::generics::text::LineHeight as GenericLineHeight; > use values::generics::text::MozTabSize as GenericMozTabSize; > use values::generics::text::Spacing; >-use values::specified::{AllowQuirks, Integer, NonNegativeNumber, Number}; > use values::specified::length::{FontRelativeLength, Length, LengthOrPercentage, NoCalcLength}; > use values::specified::length::{NonNegativeLength, NonNegativeLengthOrPercentage}; >+use values::specified::{AllowQuirks, Integer, NonNegativeNumber, Number}; > > /// A specified type for the `initial-letter` property. > pub type InitialLetter = GenericInitialLetter<Number, Integer>; > > /// A specified value for the `letter-spacing` property. > pub type LetterSpacing = Spacing<Length>; > > /// A specified value for the `word-spacing` property. >@@ -88,18 +88,21 @@ impl Parse for LineHeight { > let location = input.current_source_location(); > let ident = input.expect_ident()?; > match ident { > ref ident if ident.eq_ignore_ascii_case("normal") => Ok(GenericLineHeight::Normal), > #[cfg(feature = "gecko")] > ref ident if ident.eq_ignore_ascii_case("-moz-block-height") => > { > Ok(GenericLineHeight::MozBlockHeight) >- }, >- ident => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))), >+ } >+ ident => { >+ Err(location >+ .new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))) >+ } > } > } > } > > impl ToComputedValue for LineHeight { > type ComputedValue = ComputedLineHeight; > > #[inline] >@@ -107,59 +110,59 @@ impl ToComputedValue for LineHeight { > use values::computed::Length as ComputedLength; > use values::specified::length::FontBaseSize; > match *self { > GenericLineHeight::Normal => GenericLineHeight::Normal, > #[cfg(feature = "gecko")] > GenericLineHeight::MozBlockHeight => GenericLineHeight::MozBlockHeight, > GenericLineHeight::Number(number) => { > GenericLineHeight::Number(number.to_computed_value(context)) >- }, >+ } > GenericLineHeight::Length(ref non_negative_lop) => { > let result = match non_negative_lop.0 { > LengthOrPercentage::Length(NoCalcLength::Absolute(ref abs)) => { > context > .maybe_zoom_text(abs.to_computed_value(context).into()) > .0 >- }, >+ } > LengthOrPercentage::Length(ref length) => length.to_computed_value(context), > LengthOrPercentage::Percentage(ref p) => FontRelativeLength::Em(p.0) > .to_computed_value(context, FontBaseSize::CurrentStyle), > LengthOrPercentage::Calc(ref calc) => { > let computed_calc = > calc.to_computed_value_zoomed(context, FontBaseSize::CurrentStyle); > let font_relative_length = > FontRelativeLength::Em(computed_calc.percentage()) > .to_computed_value(context, FontBaseSize::CurrentStyle) > .px(); > > let absolute_length = computed_calc.unclamped_length().px(); > let pixel = computed_calc > .clamping_mode > .clamp(absolute_length + font_relative_length); > ComputedLength::new(pixel) >- }, >+ } > }; > GenericLineHeight::Length(result.into()) >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > match *computed { > GenericLineHeight::Normal => GenericLineHeight::Normal, > #[cfg(feature = "gecko")] > GenericLineHeight::MozBlockHeight => GenericLineHeight::MozBlockHeight, > GenericLineHeight::Number(ref number) => { > GenericLineHeight::Number(NonNegativeNumber::from_computed_value(number)) >- }, >+ } > GenericLineHeight::Length(ref length) => { > GenericLineHeight::Length(NoCalcLength::from_computed_value(&length.0).into()) >- }, >+ } > } > } > } > > /// A generic value for the `text-overflow` property. > #[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum TextOverflowSide { > /// Clip inline content. >@@ -180,17 +183,17 @@ impl Parse for TextOverflowSide { > Token::Ident(ref ident) => { > match_ignore_ascii_case! { ident, > "clip" => Ok(TextOverflowSide::Clip), > "ellipsis" => Ok(TextOverflowSide::Ellipsis), > _ => Err(location.new_custom_error( > SelectorParseErrorKind::UnexpectedIdent(ident.clone()) > )) > } >- }, >+ } > Token::QuotedString(ref v) => Ok(TextOverflowSide::String( > v.as_ref().to_owned().into_boxed_str(), > )), > ref t => Err(location.new_unexpected_token_error(t.clone())), > } > } > } > >@@ -519,29 +522,29 @@ impl ToComputedValue for TextAlign { > let ltr = _context.builder.inherited_writing_mode().is_bidi_ltr(); > match (parent, ltr) { > (TextAlignKeyword::Start, true) => TextAlignKeyword::Left, > (TextAlignKeyword::Start, false) => TextAlignKeyword::Right, > (TextAlignKeyword::End, true) => TextAlignKeyword::Right, > (TextAlignKeyword::End, false) => TextAlignKeyword::Left, > _ => parent, > } >- }, >+ } > #[cfg(feature = "gecko")] > TextAlign::MozCenterOrInherit => { > let parent = _context > .builder > .get_parent_inherited_text() > .clone_text_align(); > if parent == TextAlignKeyword::Start { > TextAlignKeyword::Center > } else { > parent > } >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > TextAlign::Keyword(*computed) > } > } >@@ -566,44 +569,42 @@ pub enum TextEmphasisKeywordValue { > Shape(TextEmphasisShapeKeyword), > /// <fill> <shape> > FillAndShape(TextEmphasisFillMode, TextEmphasisShapeKeyword), > } > > impl TextEmphasisKeywordValue { > fn fill(&self) -> Option<TextEmphasisFillMode> { > match *self { >- TextEmphasisKeywordValue::Fill(fill) | >- TextEmphasisKeywordValue::FillAndShape(fill, _) => Some(fill), >+ TextEmphasisKeywordValue::Fill(fill) >+ | TextEmphasisKeywordValue::FillAndShape(fill, _) => Some(fill), > _ => None, > } > } > > fn shape(&self) -> Option<TextEmphasisShapeKeyword> { > match *self { >- TextEmphasisKeywordValue::Shape(shape) | >- TextEmphasisKeywordValue::FillAndShape(_, shape) => Some(shape), >+ TextEmphasisKeywordValue::Shape(shape) >+ | TextEmphasisKeywordValue::FillAndShape(_, shape) => Some(shape), > _ => None, > } > } > } > > /// Fill mode for the text-emphasis-style property >-#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, >- ToCss)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum TextEmphasisFillMode { > /// `filled` > Filled, > /// `open` > Open, > } > > /// Shape keyword for the text-emphasis-style property >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToCss)] >+#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, SpecifiedValueInfo, ToCss)] > pub enum TextEmphasisShapeKeyword { > /// `dot` > Dot, > /// `circle` > Circle, > /// `double-circle` > DoubleCircle, > /// `triangle` >@@ -648,47 +649,47 @@ impl TextEmphasisShapeKeyword { > > impl ToComputedValue for TextEmphasisStyle { > type ComputedValue = ComputedTextEmphasisStyle; > > #[inline] > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > TextEmphasisStyle::Keyword(ref keyword) => { >- let default_shape = if context.style().get_inherited_box().clone_writing_mode() == >- SpecifiedWritingMode::HorizontalTb >+ let default_shape = if context.style().get_inherited_box().clone_writing_mode() >+ == SpecifiedWritingMode::HorizontalTb > { > TextEmphasisShapeKeyword::Circle > } else { > TextEmphasisShapeKeyword::Sesame > }; > ComputedTextEmphasisStyle::Keyword(ComputedTextEmphasisKeywordValue { > fill: keyword.fill().unwrap_or(TextEmphasisFillMode::Filled), > shape: keyword.shape().unwrap_or(default_shape), > }) >- }, >+ } > TextEmphasisStyle::None => ComputedTextEmphasisStyle::None, > TextEmphasisStyle::String(ref s) => { > // Passing `true` to iterate over extended grapheme clusters, following > // recommendation at http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries > let string = s.graphemes(true).next().unwrap_or("").to_string(); > ComputedTextEmphasisStyle::String(string) >- }, >+ } > } > } > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > match *computed { > ComputedTextEmphasisStyle::Keyword(ref keyword) => TextEmphasisStyle::Keyword( > TextEmphasisKeywordValue::FillAndShape(keyword.fill, keyword.shape), > ), > ComputedTextEmphasisStyle::None => TextEmphasisStyle::None, > ComputedTextEmphasisStyle::String(ref string) => { > TextEmphasisStyle::String(string.clone()) >- }, >+ } > } > } > } > > impl Parse for TextEmphasisStyle { > fn parse<'i, 't>( > _context: &ParserContext, > input: &mut Parser<'i, 't>, >@@ -719,38 +720,59 @@ impl Parse for TextEmphasisStyle { > (None, Some(shape)) => TextEmphasisKeywordValue::Shape(shape), > _ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), > }; > Ok(TextEmphasisStyle::Keyword(keyword_value)) > } > } > > /// The allowed horizontal values for the `text-emphasis-position` property. >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum TextEmphasisHorizontalWritingModeValue { > /// Draw marks over the text in horizontal writing mode. > Over, > /// Draw marks under the text in horizontal writing mode. > Under, > } > > /// The allowed vertical values for the `text-emphasis-position` property. >-#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, >- SpecifiedValueInfo, ToComputedValue, ToCss)] >+#[derive( >+ Clone, >+ Copy, >+ Debug, >+ Eq, >+ MallocSizeOf, >+ Parse, >+ PartialEq, >+ SpecifiedValueInfo, >+ ToComputedValue, >+ ToCss, >+)] > pub enum TextEmphasisVerticalWritingModeValue { > /// Draws marks to the right of the text in vertical writing mode. > Right, > /// Draw marks to the left of the text in vertical writing mode. > Left, > } > > /// Specified value of `text-emphasis-position` property. >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue, ToCss)] >+#[derive( >+ Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue, ToCss, >+)] > pub struct TextEmphasisPosition( > pub TextEmphasisHorizontalWritingModeValue, > pub TextEmphasisVerticalWritingModeValue, > ); > > impl TextEmphasisPosition { > #[inline] > /// Returns the initial value of `text-emphasis-position` >@@ -810,28 +832,28 @@ impl From<u8> for TextEmphasisPosition { > #[cfg(feature = "gecko")] > impl From<TextEmphasisPosition> for u8 { > fn from(v: TextEmphasisPosition) -> u8 { > use gecko_bindings::structs; > > let mut result = match v.0 { > TextEmphasisHorizontalWritingModeValue::Over => { > structs::NS_STYLE_TEXT_EMPHASIS_POSITION_OVER >- }, >+ } > TextEmphasisHorizontalWritingModeValue::Under => { > structs::NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER >- }, >+ } > }; > match v.1 { > TextEmphasisVerticalWritingModeValue::Right => { > result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT; >- }, >+ } > TextEmphasisVerticalWritingModeValue::Left => { > result |= structs::NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT; >- }, >+ } > }; > result as u8 > } > } > > /// A specified value for the `-moz-tab-size` property. > pub type MozTabSize = GenericMozTabSize<NonNegativeNumber, NonNegativeLength>; > >@@ -841,13 +863,12 @@ impl Parse for MozTabSize { > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > if let Ok(number) = input.try(|i| NonNegativeNumber::parse(context, i)) { > // Numbers need to be parsed first because `0` must be recognised > // as the number `0` and not the length `0px`. > return Ok(GenericMozTabSize::Number(number)); > } > Ok(GenericMozTabSize::Length(NonNegativeLength::parse( >- context, >- input, >+ context, input, > )?)) > } > } >diff --git a/servo/components/style/values/specified/time.rs b/servo/components/style/values/specified/time.rs >index 107c45b2d488..e8a790793ead 100644 >--- a/servo/components/style/values/specified/time.rs >+++ b/servo/components/style/values/specified/time.rs >@@ -2,22 +2,22 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified time values. > > use cssparser::{Parser, Token}; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use style_traits::values::specified::AllowedNumericType; >-use values::CSSFloat; >-use values::computed::{Context, ToComputedValue}; >+use style_traits::{CssWriter, ParseError, SpecifiedValueInfo, StyleParseErrorKind, ToCss}; > use values::computed::time::Time as ComputedTime; >+use values::computed::{Context, ToComputedValue}; > use values::specified::calc::CalcNode; >+use values::CSSFloat; > > /// A time value according to CSS-VALUES § 6.2. > #[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)] > pub struct Time { > seconds: CSSFloat, > unit: TimeUnit, > was_calc: bool, > } >@@ -87,22 +87,23 @@ impl Time { > match input.next() { > // Note that we generally pass ParserContext to is_ok() to check > // that the ParserMode of the ParserContext allows all numeric > // values for SMIL regardless of clamping_mode, but in this Time > // value case, the value does not animate for SMIL at all, so we use > // ParsingMode::DEFAULT directly. > Ok(&Token::Dimension { > value, ref unit, .. >- }) if clamping_mode.is_ok(ParsingMode::DEFAULT, value) => >+ }) >+ if clamping_mode.is_ok(ParsingMode::DEFAULT, value) => > { > return Time::parse_dimension(value, unit, /* from_calc = */ false) > .map_err(|()| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)); > } >- Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {}, >+ Ok(&Token::Function(ref name)) if name.eq_ignore_ascii_case("calc") => {} > Ok(t) => return Err(location.new_unexpected_token_error(t.clone())), > Err(e) => return Err(e.into()), > } > match input.parse_nested_block(|i| CalcNode::parse_time(context, i)) { > Ok(time) if clamping_mode.is_ok(ParsingMode::DEFAULT, time.seconds) => Ok(time), > _ => Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)), > } > } >@@ -148,21 +149,21 @@ impl ToCss for Time { > { > if self.was_calc { > dest.write_str("calc(")?; > } > match self.unit { > TimeUnit::Second => { > self.seconds.to_css(dest)?; > dest.write_str("s")?; >- }, >+ } > TimeUnit::Millisecond => { > (self.seconds * 1000.).to_css(dest)?; > dest.write_str("ms")?; >- }, >+ } > } > if self.was_calc { > dest.write_str(")")?; > } > Ok(()) > } > } > >diff --git a/servo/components/style/values/specified/transform.rs b/servo/components/style/values/specified/transform.rs >index 835d505836c0..9e3d660f15ea 100644 >--- a/servo/components/style/values/specified/transform.rs >+++ b/servo/components/style/values/specified/transform.rs >@@ -3,23 +3,23 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified types for CSS values that are related to transformations. > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use selectors::parser::SelectorParseErrorKind; > use style_traits::{ParseError, StyleParseErrorKind}; >+use values::computed::transform::TimingFunction as ComputedTimingFunction; > use values::computed::{Context, LengthOrPercentage as ComputedLengthOrPercentage}; > use values::computed::{Percentage as ComputedPercentage, ToComputedValue}; >-use values::computed::transform::TimingFunction as ComputedTimingFunction; > use values::generics::transform as generic; > use values::generics::transform::{Matrix, Matrix3D, StepPosition, TimingKeyword}; >-use values::specified::{self, Angle, Integer, Length, LengthOrPercentage, Number}; > use values::specified::position::{Side, X, Y}; >+use values::specified::{self, Angle, Integer, Length, LengthOrPercentage, Number}; > > pub use values::generics::transform::TransformStyle; > > /// A single operation in a specified CSS `transform` > pub type TransformOperation = > generic::TransformOperation<Angle, Number, Length, Integer, LengthOrPercentage>; > > /// A specified CSS `transform` >@@ -265,27 +265,27 @@ impl Parse for TransformOrigin { > let y_origin = OriginComponent::Center; > if let Ok(x_keyword) = input.try(X::parse) { > let x_origin = OriginComponent::Side(x_keyword); > let depth = parse_depth(input); > return Ok(Self::new(x_origin, y_origin, depth)); > } > let depth = Length::from_px(0.); > return Ok(Self::new(x_origin, y_origin, depth)); >- }, >+ } > Ok(x_origin) => { > if let Ok(y_origin) = input.try(|i| OriginComponent::parse(context, i)) { > let depth = parse_depth(input); > return Ok(Self::new(x_origin, y_origin, depth)); > } > let y_origin = OriginComponent::Center; > let depth = Length::from_px(0.); > return Ok(Self::new(x_origin, y_origin, depth)); >- }, >- Err(_) => {}, >+ } >+ Err(_) => {} > } > let y_keyword = Y::parse(input)?; > let y_origin = OriginComponent::Side(y_keyword); > if let Ok(x_keyword) = input.try(X::parse) { > let x_origin = OriginComponent::Side(x_keyword); > let depth = parse_depth(input); > return Ok(Self::new(x_origin, y_origin, depth)); > } >@@ -324,22 +324,22 @@ where > S: Side, > { > type ComputedValue = ComputedLengthOrPercentage; > > fn to_computed_value(&self, context: &Context) -> Self::ComputedValue { > match *self { > OriginComponent::Center => { > ComputedLengthOrPercentage::Percentage(ComputedPercentage(0.5)) >- }, >+ } > OriginComponent::Length(ref length) => length.to_computed_value(context), > OriginComponent::Side(ref keyword) => { > let p = ComputedPercentage(if keyword.is_start() { 0. } else { 1. }); > ComputedLengthOrPercentage::Percentage(p) >- }, >+ } > } > } > > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > OriginComponent::Length(ToComputedValue::from_computed_value(computed)) > } > } > >@@ -431,23 +431,23 @@ impl ToComputedValue for TimingFunction { > generic::TimingFunction::Keyword(keyword) => generic::TimingFunction::Keyword(keyword), > generic::TimingFunction::CubicBezier { x1, y1, x2, y2 } => { > generic::TimingFunction::CubicBezier { > x1: x1.to_computed_value(context), > y1: y1.to_computed_value(context), > x2: x2.to_computed_value(context), > y2: y2.to_computed_value(context), > } >- }, >+ } > generic::TimingFunction::Steps(steps, position) => { > generic::TimingFunction::Steps(steps.to_computed_value(context) as u32, position) >- }, >+ } > generic::TimingFunction::Frames(frames) => { > generic::TimingFunction::Frames(frames.to_computed_value(context) as u32) >- }, >+ } > } > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > match *computed { > generic::TimingFunction::Keyword(keyword) => generic::TimingFunction::Keyword(keyword), > generic::TimingFunction::CubicBezier { >@@ -462,17 +462,17 @@ impl ToComputedValue for TimingFunction { > y2: Number::from_computed_value(y2), > }, > generic::TimingFunction::Steps(steps, position) => generic::TimingFunction::Steps( > Integer::from_computed_value(&(steps as i32)), > position, > ), > generic::TimingFunction::Frames(frames) => { > generic::TimingFunction::Frames(Integer::from_computed_value(&(frames as i32))) >- }, >+ } > } > } > } > > /// A specified CSS `rotate` > pub type Rotate = generic::Rotate<Number, Angle>; > > impl Parse for Rotate { >diff --git a/servo/components/style/values/specified/ui.rs b/servo/components/style/values/specified/ui.rs >index e912c24b8080..46826f8d367a 100644 >--- a/servo/components/style/values/specified/ui.rs >+++ b/servo/components/style/values/specified/ui.rs >@@ -2,23 +2,23 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Specified types for UI properties. > > use cssparser::Parser; > use parser::{Parse, ParserContext}; > use std::fmt::{self, Write}; >-use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use style_traits::cursor::CursorKind; >-use values::{Auto, Either}; >+use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss}; > use values::generics::ui as generics; >-use values::specified::Number; > use values::specified::color::Color; > use values::specified::url::SpecifiedImageUrl; >+use values::specified::Number; >+use values::{Auto, Either}; > > /// auto | <color> > pub type ColorOrAuto = Either<Color, Auto>; > > /// A specified value for the `cursor` property. > pub type Cursor = generics::Cursor<CursorImage>; > > /// A specified value for item of `image cursors`. >@@ -47,19 +47,18 @@ impl Parse for Cursor { > > impl Parse for CursorKind { > fn parse<'i, 't>( > _context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { > let location = input.current_source_location(); > let ident = input.expect_ident()?; >- CursorKind::from_css_keyword(&ident).map_err(|_| { >- location.new_custom_error(StyleParseErrorKind::UnspecifiedError) >- }) >+ CursorKind::from_css_keyword(&ident) >+ .map_err(|_| location.new_custom_error(StyleParseErrorKind::UnspecifiedError)) > } > } > > impl Parse for CursorImage { > fn parse<'i, 't>( > context: &ParserContext, > input: &mut Parser<'i, 't>, > ) -> Result<Self, ParseError<'i>> { >@@ -69,18 +68,17 @@ impl Parse for CursorImage { > Ok(number) => Some((number, Number::parse(context, input)?)), > Err(_) => None, > }, > }) > } > } > > /// Specified value of `-moz-force-broken-image-icon` >-#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, >- ToComputedValue)] >+#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq, SpecifiedValueInfo, ToComputedValue)] > pub struct MozForceBrokenImageIcon(pub bool); > > impl MozForceBrokenImageIcon { > /// Return initial value of -moz-force-broken-image-icon which is false. > #[inline] > pub fn false_value() -> MozForceBrokenImageIcon { > MozForceBrokenImageIcon(false) > } >diff --git a/servo/components/style/values/specified/url.rs b/servo/components/style/values/specified/url.rs >index d5a165f22d81..fe68c3143f5b 100644 >--- a/servo/components/style/values/specified/url.rs >+++ b/servo/components/style/values/specified/url.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Common handling for the specified value CSS url() values. > > use values::generics::url::UrlOrNone as GenericUrlOrNone; > >-#[cfg(feature = "servo")] >-pub use servo::url::{SpecifiedImageUrl, SpecifiedUrl}; > #[cfg(feature = "gecko")] > pub use gecko::url::{SpecifiedImageUrl, SpecifiedUrl}; >+#[cfg(feature = "servo")] >+pub use servo::url::{SpecifiedImageUrl, SpecifiedUrl}; > > /// Specified <url> | <none> > pub type UrlOrNone = GenericUrlOrNone<SpecifiedUrl>; > > /// Specified image <url> | <none> > pub type ImageUrlOrNone = GenericUrlOrNone<SpecifiedImageUrl>; >diff --git a/servo/components/style_derive/cg.rs b/servo/components/style_derive/cg.rs >index b370a5c55d4b..2a835b47abe3 100644 >--- a/servo/components/style_derive/cg.rs >+++ b/servo/components/style_derive/cg.rs >@@ -4,171 +4,186 @@ > > use darling::{FromDeriveInput, FromField, FromVariant}; > use quote::Tokens; > use syn::{self, AngleBracketedGenericArguments, Binding, DeriveInput, Field}; > use syn::{GenericArgument, GenericParam, Ident, Path}; > use syn::{PathArguments, PathSegment, QSelf, Type, TypeArray}; > use syn::{TypeParam, TypeParen, TypePath, TypeSlice, TypeTuple}; > use syn::{Variant, WherePredicate}; >-use synstructure::{self, BindingInfo, BindStyle, VariantAst, VariantInfo}; >+use synstructure::{self, BindStyle, BindingInfo, VariantAst, VariantInfo}; > >-pub fn add_predicate( >- where_clause: &mut Option<syn::WhereClause>, >- pred: WherePredicate, >-) { >- where_clause.get_or_insert(parse_quote!(where)).predicates.push(pred); >+pub fn add_predicate(where_clause: &mut Option<syn::WhereClause>, pred: WherePredicate) { >+ where_clause >+ .get_or_insert(parse_quote!(where)) >+ .predicates >+ .push(pred); > } > >-pub fn fmap_match<F>( >- input: &DeriveInput, >- bind_style: BindStyle, >- mut f: F, >-) -> Tokens >+pub fn fmap_match<F>(input: &DeriveInput, bind_style: BindStyle, mut f: F) -> Tokens > where > F: FnMut(BindingInfo) -> Tokens, > { > let mut s = synstructure::Structure::new(input); >- s.variants_mut().iter_mut().for_each(|v| { v.bind_with(|_| bind_style); }); >+ s.variants_mut().iter_mut().for_each(|v| { >+ v.bind_with(|_| bind_style); >+ }); > s.each_variant(|variant| { > let (mapped, mapped_fields) = value(variant, "mapped"); > let fields_pairs = variant.bindings().into_iter().zip(mapped_fields); > let mut computations = quote!(); > computations.append_all(fields_pairs.map(|(field, mapped_field)| { > let expr = f(field.clone()); > quote! { let #mapped_field = #expr; } > })); > computations.append_all(mapped); > Some(computations) > }) > } > >-pub fn fmap_trait_output( >- input: &DeriveInput, >- trait_path: &Path, >- trait_output: Ident, >-) -> Path { >+pub fn fmap_trait_output(input: &DeriveInput, trait_path: &Path, trait_output: Ident) -> Path { > let segment = PathSegment { > ident: input.ident.clone(), > arguments: PathArguments::AngleBracketed(AngleBracketedGenericArguments { >- args: input.generics.params.iter().map(|arg| { >- match arg { >- &GenericParam::Lifetime(ref data) => GenericArgument::Lifetime(data.lifetime.clone()), >+ args: input >+ .generics >+ .params >+ .iter() >+ .map(|arg| match arg { >+ &GenericParam::Lifetime(ref data) => { >+ GenericArgument::Lifetime(data.lifetime.clone()) >+ } > &GenericParam::Type(ref data) => { > let ident = data.ident; > GenericArgument::Type( > parse_quote!(<#ident as ::#trait_path>::#trait_output), > ) >- }, >- ref arg => panic!("arguments {:?} cannot be mapped yet", arg) >- } >- }).collect(), >+ } >+ ref arg => panic!("arguments {:?} cannot be mapped yet", arg), >+ }).collect(), > colon2_token: Default::default(), > gt_token: Default::default(), > lt_token: Default::default(), >- >- }) >+ }), > }; > segment.into() > } > > pub fn map_type_params<F>(ty: &Type, params: &[&TypeParam], f: &mut F) -> Type > where > F: FnMut(&Ident) -> Type, > { > match *ty { >- Type::Slice(ref inner) => { >- Type::from(TypeSlice { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() }) >- }, >- Type::Array(ref inner) => { //ref ty, ref expr) => { >- Type::from(TypeArray { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() }) >- }, >+ Type::Slice(ref inner) => Type::from(TypeSlice { >+ elem: Box::new(map_type_params(&inner.elem, params, f)), >+ ..inner.clone() >+ }), >+ Type::Array(ref inner) => { >+ //ref ty, ref expr) => { >+ Type::from(TypeArray { >+ elem: Box::new(map_type_params(&inner.elem, params, f)), >+ ..inner.clone() >+ }) >+ } > ref ty @ Type::Never(_) => ty.clone(), >- Type::Tuple(ref inner) => { >- Type::from( >- TypeTuple { >- elems: inner.elems.iter().map(|ty| map_type_params(&ty, params, f)).collect(), >- ..inner.clone() >- } >- ) >- }, >- Type::Path(TypePath { qself: None, ref path }) => { >+ Type::Tuple(ref inner) => Type::from(TypeTuple { >+ elems: inner >+ .elems >+ .iter() >+ .map(|ty| map_type_params(&ty, params, f)) >+ .collect(), >+ ..inner.clone() >+ }), >+ Type::Path(TypePath { >+ qself: None, >+ ref path, >+ }) => { > if let Some(ident) = path_to_ident(path) { > if params.iter().any(|param| param.ident == ident) { > return f(ident); > } > } >- Type::from(TypePath { qself: None, path: map_type_params_in_path(path, params, f) }) >- } >- Type::Path(TypePath { ref qself, ref path }) => { > Type::from(TypePath { >- qself: qself.as_ref().map(|qself| { >- QSelf { >- ty: Box::new(map_type_params(&qself.ty, params, f)), >- position: qself.position, >- ..qself.clone() >- } >- }), >+ qself: None, > path: map_type_params_in_path(path, params, f), > }) >- }, >- Type::Paren(ref inner) => { >- Type::from(TypeParen { elem: Box::new(map_type_params(&inner.elem, params, f)), ..inner.clone() }) >- }, >+ } >+ Type::Path(TypePath { >+ ref qself, >+ ref path, >+ }) => Type::from(TypePath { >+ qself: qself.as_ref().map(|qself| QSelf { >+ ty: Box::new(map_type_params(&qself.ty, params, f)), >+ position: qself.position, >+ ..qself.clone() >+ }), >+ path: map_type_params_in_path(path, params, f), >+ }), >+ Type::Paren(ref inner) => Type::from(TypeParen { >+ elem: Box::new(map_type_params(&inner.elem, params, f)), >+ ..inner.clone() >+ }), > ref ty => panic!("type {:?} cannot be mapped yet", ty), > } > } > > fn map_type_params_in_path<F>(path: &Path, params: &[&TypeParam], f: &mut F) -> Path > where > F: FnMut(&Ident) -> Type, > { > Path { > leading_colon: path.leading_colon, >- segments: path.segments.iter().map(|segment| { >- PathSegment { >+ segments: path >+ .segments >+ .iter() >+ .map(|segment| PathSegment { > ident: segment.ident.clone(), > arguments: match segment.arguments { > PathArguments::AngleBracketed(ref data) => { > PathArguments::AngleBracketed(AngleBracketedGenericArguments { >- args: data.args.iter().map(|arg| { >- match arg { >+ args: data >+ .args >+ .iter() >+ .map(|arg| match arg { > ty @ &GenericArgument::Lifetime(_) => ty.clone(), > &GenericArgument::Type(ref data) => { > GenericArgument::Type(map_type_params(data, params, f)) >- }, >- &GenericArgument::Binding(ref data) => GenericArgument::Binding(Binding { >- ty: map_type_params(&data.ty, params, f), >- ..data.clone() >- }), >- ref arg => panic!("arguments {:?} cannot be mapped yet", arg) >- } >- }).collect(), >+ } >+ &GenericArgument::Binding(ref data) => { >+ GenericArgument::Binding(Binding { >+ ty: map_type_params(&data.ty, params, f), >+ ..data.clone() >+ }) >+ } >+ ref arg => panic!("arguments {:?} cannot be mapped yet", arg), >+ }).collect(), > ..data.clone() > }) >- }, >+ } > ref arg @ PathArguments::None => arg.clone(), >- ref parameters => { >- panic!("parameters {:?} cannot be mapped yet", parameters) >- } >+ ref parameters => panic!("parameters {:?} cannot be mapped yet", parameters), > }, >- } >- }).collect(), >+ }).collect(), > } > } > > fn path_to_ident(path: &Path) -> Option<&Ident> { > match *path { >- Path { leading_colon: None, ref segments } if segments.len() == 1 => { >+ Path { >+ leading_colon: None, >+ ref segments, >+ } >+ if segments.len() == 1 => >+ { > if segments[0].arguments.is_empty() { > Some(&segments[0].ident) > } else { > None > } >- }, >+ } > _ => None, > } > } > > pub fn parse_field_attrs<A>(field: &Field) -> A > where > A: FromField, > { >@@ -198,58 +213,55 @@ where > fields: variant.fields.clone(), > discriminant: variant.discriminant.clone(), > }; > parse_variant_attrs(&v) > } > > pub fn parse_variant_attrs<A>(variant: &Variant) -> A > where >- A: FromVariant >+ A: FromVariant, > { > match A::from_variant(variant) { > Ok(attrs) => attrs, > Err(e) => panic!("failed to parse variant attributes: {}", e), > } > } > >- >-pub fn ref_pattern<'a>( >- variant: &'a VariantInfo, >- prefix: &str, >-) -> (Tokens, Vec<BindingInfo<'a>>) { >+pub fn ref_pattern<'a>(variant: &'a VariantInfo, prefix: &str) -> (Tokens, Vec<BindingInfo<'a>>) { > let mut v = variant.clone(); > v.bind_with(|_| BindStyle::Ref); >- v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::from(format!("{}_{}", b.binding, prefix)) }); >+ v.bindings_mut() >+ .iter_mut() >+ .for_each(|b| b.binding = Ident::from(format!("{}_{}", b.binding, prefix))); > (v.pat(), v.bindings().iter().cloned().collect()) > } > >-pub fn value<'a>( >- variant: &'a VariantInfo, >- prefix: &str, >-) -> (Tokens, Vec<BindingInfo<'a>>) { >+pub fn value<'a>(variant: &'a VariantInfo, prefix: &str) -> (Tokens, Vec<BindingInfo<'a>>) { > let mut v = variant.clone(); >- v.bindings_mut().iter_mut().for_each(|b| { b.binding = Ident::from(format!("{}_{}", b.binding, prefix)) }); >+ v.bindings_mut() >+ .iter_mut() >+ .for_each(|b| b.binding = Ident::from(format!("{}_{}", b.binding, prefix))); > v.bind_with(|_| BindStyle::Move); > (v.pat(), v.bindings().iter().cloned().collect()) > } > > /// Transforms "FooBar" to "foo-bar". > /// > /// If the first Camel segment is "Moz", "Webkit", or "Servo", the result string > /// is prepended with "-". > pub fn to_css_identifier(mut camel_case: &str) -> String { > camel_case = camel_case.trim_right_matches('_'); > let mut first = true; > let mut result = String::with_capacity(camel_case.len()); > while let Some(segment) = split_camel_segment(&mut camel_case) { > if first { > match segment { > "Moz" | "Webkit" | "Servo" => first = false, >- _ => {}, >+ _ => {} > } > } > if !first { > result.push_str("-"); > } > first = false; > result.push_str(&segment.to_lowercase()); > } >diff --git a/servo/components/style_derive/lib.rs b/servo/components/style_derive/lib.rs >index 8c8c0705e8fd..d437fb19900f 100644 >--- a/servo/components/style_derive/lib.rs >+++ b/servo/components/style_derive/lib.rs >@@ -1,18 +1,21 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #![recursion_limit = "128"] > >-#[macro_use] extern crate darling; >+#[macro_use] >+extern crate darling; > extern crate proc_macro; >-#[macro_use] extern crate quote; >-#[macro_use] extern crate syn; >+#[macro_use] >+extern crate quote; >+#[macro_use] >+extern crate syn; > extern crate synstructure; > > use proc_macro::TokenStream; > > mod animate; > mod cg; > mod compute_squared_distance; > mod parse; >diff --git a/servo/components/style_derive/parse.rs b/servo/components/style_derive/parse.rs >index 13d8aa6f48b9..76d2c8a82fc6 100644 >--- a/servo/components/style_derive/parse.rs >+++ b/servo/components/style_derive/parse.rs >@@ -22,33 +22,33 @@ pub fn derive(input: DeriveInput) -> Tokens { > let mut saw_condition = false; > let match_body = s.variants().iter().fold(quote!(), |match_body, variant| { > let bindings = variant.bindings(); > assert!( > bindings.is_empty(), > "Parse is only supported for single-variant enums for now" > ); > >- let css_variant_attrs = >- cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast()); >- let parse_attrs = >- cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast()); >+ let css_variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&variant.ast()); >+ let parse_attrs = cg::parse_variant_attrs_from_ast::<ParseVariantAttrs>(&variant.ast()); > if css_variant_attrs.skip { > return match_body; > } > > let identifier = cg::to_css_identifier( >- &css_variant_attrs.keyword.unwrap_or(variant.ast().ident.as_ref().into()), >+ &css_variant_attrs >+ .keyword >+ .unwrap_or(variant.ast().ident.as_ref().into()), > ); > let ident = &variant.ast().ident; > > saw_condition |= parse_attrs.condition.is_some(); > let condition = match parse_attrs.condition { > Some(ref p) => quote! { if #p(context) }, >- None => quote! { }, >+ None => quote!{}, > }; > > let mut body = quote! { > #match_body > #identifier #condition => Ok(#name::#ident), > }; > > let aliases = match parse_attrs.aliases { >@@ -82,17 +82,16 @@ pub fn derive(input: DeriveInput) -> Tokens { > ::cssparser::Token::Ident(ident.clone()) > )) > } > } > } else { > quote! { Self::parse(input) } > }; > >- > let parse_trait_impl = quote! { > impl ::parser::Parse for #name { > #[inline] > fn parse<'i, 't>( > #context_ident: &::parser::ParserContext, > input: &mut ::cssparser::Parser<'i, 't>, > ) -> Result<Self, ::style_traits::ParseError<'i>> { > #parse_body >diff --git a/servo/components/style_derive/specified_value_info.rs b/servo/components/style_derive/specified_value_info.rs >index b707ec2c69fc..186aadd2866e 100644 >--- a/servo/components/style_derive/specified_value_info.rs >+++ b/servo/components/style_derive/specified_value_info.rs >@@ -12,18 +12,18 @@ pub fn derive(mut input: DeriveInput) -> Tokens { > let css_attrs = cg::parse_input_attrs::<CssInputAttrs>(&input); > let mut types = vec![]; > let mut values = vec![]; > > let input_ident = input.ident; > let input_name = || cg::to_css_identifier(input_ident.as_ref()); > if let Some(function) = css_attrs.function { > values.push(function.explicit().unwrap_or_else(input_name)); >- // If the whole value is wrapped in a function, value types of >- // its fields should not be propagated. >+ // If the whole value is wrapped in a function, value types of >+ // its fields should not be propagated. > } else { > let mut where_clause = input.generics.where_clause.take(); > for param in input.generics.type_params() { > cg::add_predicate( > &mut where_clause, > parse_quote!(#param: ::style_traits::SpecifiedValueInfo), > ); > } >@@ -79,23 +79,27 @@ pub fn derive(mut input: DeriveInput) -> Tokens { > let info_attrs = cg::parse_input_attrs::<ValueInfoInputAttrs>(&input); > if let Some(other_values) = info_attrs.other_values { > for value in other_values.split(",") { > values.push(value.to_string()); > } > } > > let mut types_value = quote!(0); >- types_value.append_all(types.iter().map(|ty| quote! { >- | <#ty as ::style_traits::SpecifiedValueInfo>::SUPPORTED_TYPES >+ types_value.append_all(types.iter().map(|ty| { >+ quote! { >+ | <#ty as ::style_traits::SpecifiedValueInfo>::SUPPORTED_TYPES >+ } > })); > > let mut nested_collects = quote!(); >- nested_collects.append_all(types.iter().map(|ty| quote! { >- <#ty as ::style_traits::SpecifiedValueInfo>::collect_completion_keywords(_f); >+ nested_collects.append_all(types.iter().map(|ty| { >+ quote! { >+ <#ty as ::style_traits::SpecifiedValueInfo>::collect_completion_keywords(_f); >+ } > })); > > if let Some(ty) = info_attrs.ty { > types_value.append_all(quote! { > | ::style_traits::CssType::#ty > }); > } > >@@ -139,17 +143,19 @@ fn derive_struct_fields<'a>( > let info_attrs = cg::parse_field_attrs::<ValueInfoFieldAttrs>(field); > if let Some(other_values) = info_attrs.other_values { > for value in other_values.split(",") { > values.push(value.to_string()); > } > } > let css_attrs = cg::parse_field_attrs::<CssFieldAttrs>(field); > if css_attrs.represents_keyword { >- let ident = field.ident.as_ref() >+ let ident = field >+ .ident >+ .as_ref() > .expect("only named field should use represents_keyword"); > values.push(cg::to_css_identifier(ident.as_ref())); > return None; > } > if let Some(if_empty) = css_attrs.if_empty { > values.push(if_empty); > } > if !css_attrs.skip { >diff --git a/servo/components/style_derive/to_animated_value.rs b/servo/components/style_derive/to_animated_value.rs >index a7378b70145e..f9be9391ef66 100644 >--- a/servo/components/style_derive/to_animated_value.rs >+++ b/servo/components/style_derive/to_animated_value.rs >@@ -11,22 +11,26 @@ pub fn derive(mut input: DeriveInput) -> quote::Tokens { > let mut where_clause = input.generics.where_clause.take(); > for param in input.generics.type_params() { > cg::add_predicate( > &mut where_clause, > parse_quote!(#param: ::values::animated::ToAnimatedValue), > ); > } > >- let to_body = cg::fmap_match(&input, BindStyle::Move, |binding| { >- quote!(::values::animated::ToAnimatedValue::to_animated_value(#binding)) >- }); >- let from_body = cg::fmap_match(&input, BindStyle::Move, |binding| { >- quote!(::values::animated::ToAnimatedValue::from_animated_value(#binding)) >- }); >+ let to_body = cg::fmap_match( >+ &input, >+ BindStyle::Move, >+ |binding| quote!(::values::animated::ToAnimatedValue::to_animated_value(#binding)), >+ ); >+ let from_body = cg::fmap_match( >+ &input, >+ BindStyle::Move, >+ |binding| quote!(::values::animated::ToAnimatedValue::from_animated_value(#binding)), >+ ); > > input.generics.where_clause = where_clause; > let name = &input.ident; > let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); > let animated_value_type = cg::fmap_trait_output( > &input, > &parse_quote!(values::animated::ToAnimatedValue), > "AnimatedValue".into(), >diff --git a/servo/components/style_derive/to_computed_value.rs b/servo/components/style_derive/to_computed_value.rs >index 9b7544ffbb85..e34690bc999e 100644 >--- a/servo/components/style_derive/to_computed_value.rs >+++ b/servo/components/style_derive/to_computed_value.rs >@@ -18,19 +18,21 @@ pub fn derive(mut input: DeriveInput) -> Tokens { > ); > } > > let to_body = cg::fmap_match(&input, BindStyle::Ref, |binding| { > let attrs = cg::parse_field_attrs::<ComputedValueAttrs>(&binding.ast()); > if attrs.field_bound { > let ty = &binding.ast().ty; > >- let output_type = cg::map_type_params(ty, &params, &mut |ident| { >- parse_quote!(<#ident as ::values::computed::ToComputedValue>::ComputedValue) >- }); >+ let output_type = cg::map_type_params( >+ ty, >+ &params, >+ &mut |ident| parse_quote!(<#ident as ::values::computed::ToComputedValue>::ComputedValue), >+ ); > > cg::add_predicate( > &mut where_clause, > parse_quote!( > #ty: ::values::computed::ToComputedValue<ComputedValue = #output_type> > ), > ); > } >@@ -66,17 +68,17 @@ pub fn derive(mut input: DeriveInput) -> Tokens { > ::std::clone::Clone::clone(self) > } > > #[inline] > fn from_computed_value(computed: &Self::ComputedValue) -> Self { > ::std::clone::Clone::clone(computed) > } > } >- } >+ }; > } > > let computed_value_type = cg::fmap_trait_output( > &input, > &parse_quote!(values::computed::ToComputedValue), > "ComputedValue".into(), > ); > >diff --git a/servo/components/style_derive/to_css.rs b/servo/components/style_derive/to_css.rs >index 83177f3c89fb..a5811471cb1d 100644 >--- a/servo/components/style_derive/to_css.rs >+++ b/servo/components/style_derive/to_css.rs >@@ -14,25 +14,26 @@ pub fn derive(mut input: syn::DeriveInput) -> Tokens { > cg::add_predicate( > &mut where_clause, > parse_quote!(#param: ::style_traits::ToCss), > ); > } > > let input_attrs = cg::parse_input_attrs::<CssInputAttrs>(&input); > if let Data::Enum(_) = input.data { >- assert!(input_attrs.function.is_none(), "#[css(function)] is not allowed on enums"); >+ assert!( >+ input_attrs.function.is_none(), >+ "#[css(function)] is not allowed on enums" >+ ); > assert!(!input_attrs.comma, "#[css(comma)] is not allowed on enums"); > } > > let match_body = { > let s = Structure::new(&input); >- s.each_variant(|variant| { >- derive_variant_arm(variant, &mut where_clause) >- }) >+ s.each_variant(|variant| derive_variant_arm(variant, &mut where_clause)) > }; > input.generics.where_clause = where_clause; > > let name = &input.ident; > let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl(); > > let mut impls = quote! { > impl #impl_generics ::style_traits::ToCss for #name #ty_generics #where_clause { >@@ -63,20 +64,17 @@ pub fn derive(mut input: syn::DeriveInput) -> Tokens { > } > } > }); > } > > impls > } > >-fn derive_variant_arm( >- variant: &VariantInfo, >- generics: &mut Option<WhereClause>, >-) -> Tokens { >+fn derive_variant_arm(variant: &VariantInfo, generics: &mut Option<WhereClause>) -> Tokens { > let bindings = variant.bindings(); > let identifier = cg::to_css_identifier(variant.ast().ident.as_ref()); > let ast = variant.ast(); > let variant_attrs = cg::parse_variant_attrs_from_ast::<CssVariantAttrs>(&ast); > let separator = if variant_attrs.comma { ", " } else { " " }; > > if variant_attrs.skip { > return quote!(Ok(())); >@@ -119,23 +117,25 @@ fn derive_variant_arm( > expr > } > > fn derive_variant_fields_expr( > bindings: &[BindingInfo], > where_clause: &mut Option<WhereClause>, > separator: &str, > ) -> Tokens { >- let mut iter = bindings.iter().filter_map(|binding| { >- let attrs = cg::parse_field_attrs::<CssFieldAttrs>(&binding.ast()); >- if attrs.skip { >- return None; >- } >- Some((binding, attrs)) >- }).peekable(); >+ let mut iter = bindings >+ .iter() >+ .filter_map(|binding| { >+ let attrs = cg::parse_field_attrs::<CssFieldAttrs>(&binding.ast()); >+ if attrs.skip { >+ return None; >+ } >+ Some((binding, attrs)) >+ }).peekable(); > > let (first, attrs) = match iter.next() { > Some(pair) => pair, > None => return quote! { Ok(()) }, > }; > if !attrs.iterable && iter.peek().is_none() { > if attrs.field_bound { > let ty = &first.ast().ty; >@@ -185,18 +185,21 @@ fn derive_single_field_expr( > }; > } > quote! { > for item in #field.iter() { > writer.item(&item)?; > } > } > } else if attrs.represents_keyword { >- let ident = >- field.ast().ident.as_ref().expect("Unnamed field with represents_keyword?"); >+ let ident = field >+ .ast() >+ .ident >+ .as_ref() >+ .expect("Unnamed field with represents_keyword?"); > let ident = cg::to_css_identifier(ident.as_ref()); > quote! { > if *#field { > writer.raw_item(#ident)?; > } > } > } else { > if attrs.field_bound { >diff --git a/servo/components/style_traits/lib.rs b/servo/components/style_traits/lib.rs >index 737450b5e059..8ec0ddb959c6 100644 >--- a/servo/components/style_traits/lib.rs >+++ b/servo/components/style_traits/lib.rs >@@ -3,49 +3,61 @@ > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! This module contains shared types and messages for use by devtools/script. > //! The traits are here instead of in script so that the devtools crate can be > //! modified independently of the rest of Servo. > > #![crate_name = "style_traits"] > #![crate_type = "rlib"] >- > #![deny(unsafe_code, missing_docs)] > > extern crate app_units; >-#[macro_use] extern crate bitflags; >-#[macro_use] extern crate cssparser; >+#[macro_use] >+extern crate bitflags; >+#[macro_use] >+extern crate cssparser; > extern crate euclid; > extern crate malloc_size_of; >-#[macro_use] extern crate malloc_size_of_derive; >+#[macro_use] >+extern crate malloc_size_of_derive; > extern crate selectors; >-#[cfg(feature = "servo")] #[macro_use] extern crate serde; >-#[cfg(feature = "servo")] extern crate webrender_api; >+#[cfg(feature = "servo")] >+#[macro_use] >+extern crate serde; > extern crate servo_arc; >-#[cfg(feature = "servo")] extern crate servo_atoms; >-#[cfg(feature = "servo")] extern crate servo_url; >+#[cfg(feature = "servo")] >+extern crate servo_atoms; >+#[cfg(feature = "servo")] >+extern crate servo_url; >+#[cfg(feature = "servo")] >+extern crate webrender_api; > >-#[cfg(feature = "servo")] pub use webrender_api::DevicePixel; >+#[cfg(feature = "servo")] >+pub use webrender_api::DevicePixel; > > use cssparser::{CowRcStr, Token}; > use selectors::parser::SelectorParseErrorKind; >-#[cfg(feature = "servo")] use servo_atoms::Atom; >+#[cfg(feature = "servo")] >+use servo_atoms::Atom; > > /// One hardware pixel. > /// > /// This unit corresponds to the smallest addressable element of the display hardware. > #[cfg(not(feature = "servo"))] > #[derive(Clone, Copy, Debug)] > pub enum DevicePixel {} > > /// Represents a mobile style pinch zoom factor. > /// TODO(gw): Once WR supports pinch zoom, use a type directly from webrender_api. > #[derive(Clone, Copy, Debug, PartialEq)] >-#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] >+#[cfg_attr( >+ feature = "servo", >+ derive(Deserialize, Serialize, MallocSizeOf) >+)] > pub struct PinchZoomFactor(f32); > > impl PinchZoomFactor { > /// Construct a new pinch zoom factor. > pub fn new(scale: f32) -> PinchZoomFactor { > PinchZoomFactor(scale) > } > >@@ -178,26 +190,24 @@ pub enum ValueParseErrorKind<'i> { > impl<'i> StyleParseErrorKind<'i> { > /// Create an InvalidValue parse error > pub fn new_invalid<S>(name: S, value_error: ParseError<'i>) -> ParseError<'i> > where > S: Into<CowRcStr<'i>>, > { > let name = name.into(); > let variant = match value_error.kind { >- cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => { >- match e { >- ValueParseErrorKind::InvalidColor(token) => { >- StyleParseErrorKind::InvalidColor(name, token) >- } >- ValueParseErrorKind::InvalidFilter(token) => { >- StyleParseErrorKind::InvalidFilter(name, token) >- } >+ cssparser::ParseErrorKind::Custom(StyleParseErrorKind::ValueError(e)) => match e { >+ ValueParseErrorKind::InvalidColor(token) => { >+ StyleParseErrorKind::InvalidColor(name, token) > } >- } >+ ValueParseErrorKind::InvalidFilter(token) => { >+ StyleParseErrorKind::InvalidFilter(name, token) >+ } >+ }, > _ => StyleParseErrorKind::OtherInvalidValue(name), > }; > cssparser::ParseError { > kind: cssparser::ParseErrorKind::Custom(variant), > location: value_error.location, > } > } > } >@@ -231,10 +241,14 @@ impl ParsingMode { > self.intersects(ParsingMode::ALLOW_ALL_NUMERIC_VALUES) > } > } > > #[cfg(feature = "servo")] > /// Speculatively execute paint code in the worklet thread pool. > pub trait SpeculativePainter: Send + Sync { > /// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image> >- fn speculatively_draw_a_paint_image(&self, properties: Vec<(Atom, String)>, arguments: Vec<String>); >+ fn speculatively_draw_a_paint_image( >+ &self, >+ properties: Vec<(Atom, String)>, >+ arguments: Vec<String>, >+ ); > } >diff --git a/servo/components/style_traits/specified_value_info.rs b/servo/components/style_traits/specified_value_info.rs >index e0dd5544d0a3..d16d183a132f 100644 >--- a/servo/components/style_traits/specified_value_info.rs >+++ b/servo/components/style_traits/specified_value_info.rs >@@ -105,17 +105,17 @@ impl<T: SpecifiedValueInfo> SpecifiedValueInfo for [T] { > macro_rules! impl_generic_specified_value_info { > ($ty:ident<$param:ident>) => { > impl<$param: SpecifiedValueInfo> SpecifiedValueInfo for $ty<$param> { > const SUPPORTED_TYPES: u8 = $param::SUPPORTED_TYPES; > fn collect_completion_keywords(f: KeywordsCollectFn) { > $param::collect_completion_keywords(f); > } > } >- } >+ }; > } > impl_generic_specified_value_info!(Option<T>); > impl_generic_specified_value_info!(Vec<T>); > impl_generic_specified_value_info!(Arc<T>); > impl_generic_specified_value_info!(StdArc<T>); > impl_generic_specified_value_info!(Range<Idx>); > > impl<T1, T2> SpecifiedValueInfo for (T1, T2) >diff --git a/servo/components/style_traits/values.rs b/servo/components/style_traits/values.rs >index 8b3bd13dc202..c1761bb11573 100644 >--- a/servo/components/style_traits/values.rs >+++ b/servo/components/style_traits/values.rs >@@ -1,17 +1,17 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Helper types and traits for the handling of CSS values. > > use app_units::Au; >-use cssparser::{ParseError, Parser, Token, UnicodeRange, serialize_string}; > use cssparser::ToCss as CssparserToCss; >+use cssparser::{serialize_string, ParseError, Parser, Token, UnicodeRange}; > use servo_arc::Arc; > use std::fmt::{self, Write}; > > /// Serialises a value according to its CSS representation. > /// > /// This trait is implemented for `str` and its friends, serialising the string > /// contents as a CSS quoted string. > /// >@@ -39,55 +39,72 @@ use std::fmt::{self, Write}; > /// provided the field as an argument; > /// * `#[css(represents_keyword)]` can be used on bool fields in order to > /// serialize the field name if the field is true, or nothing otherwise. It > /// also collects those keywords for `SpecifiedValueInfo`. > /// * finally, one can put `#[css(derive_debug)]` on the whole type, to > /// implement `Debug` by a single call to `ToCss::to_css`. > pub trait ToCss { > /// Serialize `self` in CSS syntax, writing to `dest`. >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write; >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write; > > /// Serialize `self` in CSS syntax and return a string. > /// > /// (This is a convenience wrapper for `to_css` and probably should not be overridden.) > #[inline] > fn to_css_string(&self) -> String { > let mut s = String::new(); > self.to_css(&mut CssWriter::new(&mut s)).unwrap(); > s > } > } > >-impl<'a, T> ToCss for &'a T where T: ToCss + ?Sized { >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+impl<'a, T> ToCss for &'a T >+where >+ T: ToCss + ?Sized, >+{ >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > (*self).to_css(dest) > } > } > > impl ToCss for str { > #[inline] >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > serialize_string(self, dest) > } > } > > impl ToCss for String { > #[inline] >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > serialize_string(self, dest) > } > } > > impl<T> ToCss for Option<T> > where > T: ToCss, > { > #[inline] >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > self.as_ref().map_or(Ok(()), |value| value.to_css(dest)) > } > } > > /// A writer tailored for serialising CSS. > /// > /// Coupled with SequenceWriter, this allows callers to transparently handle > /// things like comma-separated values etc. >@@ -98,17 +115,20 @@ pub struct CssWriter<'w, W: 'w> { > > impl<'w, W> CssWriter<'w, W> > where > W: Write, > { > /// Creates a new `CssWriter`. > #[inline] > pub fn new(inner: &'w mut W) -> Self { >- Self { inner, prefix: Some("") } >+ Self { >+ inner, >+ prefix: Some(""), >+ } > } > } > > impl<'w, W> Write for CssWriter<'w, W> > where > W: Write, > { > #[inline] >@@ -174,17 +194,17 @@ where > inner.prefix = Some(""); > } > Self { inner, separator } > } > > #[inline] > fn write_item<F>(&mut self, f: F) -> fmt::Result > where >- F: FnOnce(&mut CssWriter<'b, W>) -> fmt::Result >+ F: FnOnce(&mut CssWriter<'b, W>) -> fmt::Result, > { > let old_prefix = self.inner.prefix; > if old_prefix.is_none() { > // If there is no prefix in the inner writer, a previous > // call to this method produced output, which means we need > // to write the separator next time we produce output again. > self.inner.prefix = Some(self.separator); > } >@@ -277,66 +297,66 @@ impl Separator for Comma { > ", " > } > > fn parse<'i, 't, F, T, E>( > input: &mut Parser<'i, 't>, > parse_one: F, > ) -> Result<Vec<T>, ParseError<'i, E>> > where >- F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> >+ F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>, > { > input.parse_comma_separated(parse_one) > } > } > > impl Separator for Space { > fn separator() -> &'static str { > " " > } > > fn parse<'i, 't, F, T, E>( > input: &mut Parser<'i, 't>, > mut parse_one: F, > ) -> Result<Vec<T>, ParseError<'i, E>> > where >- F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> >+ F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>, > { >- input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. >+ input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. > let mut results = vec![parse_one(input)?]; > loop { >- input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. >+ input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. > if let Ok(item) = input.try(&mut parse_one) { > results.push(item); > } else { >- return Ok(results) >+ return Ok(results); > } > } > } > } > > impl Separator for CommaWithSpace { > fn separator() -> &'static str { > ", " > } > > fn parse<'i, 't, F, T, E>( > input: &mut Parser<'i, 't>, > mut parse_one: F, > ) -> Result<Vec<T>, ParseError<'i, E>> > where >- F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>> >+ F: for<'tt> FnMut(&mut Parser<'i, 'tt>) -> Result<T, ParseError<'i, E>>, > { >- input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. >+ input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. > let mut results = vec![parse_one(input)?]; > loop { >- input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. >+ input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. > let comma_location = input.current_source_location(); > let comma = input.try(|i| i.expect_comma()).is_ok(); >- input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. >+ input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less. > if let Ok(item) = input.try(&mut parse_one) { > results.push(item); > } else if comma { > return Err(comma_location.new_unexpected_token_error(Token::Comma)); > } else { > break; > } > } >@@ -350,55 +370,75 @@ pub trait OneOrMoreSeparated { > /// Associated type indicating which separator is used. > type S: Separator; > } > > impl OneOrMoreSeparated for UnicodeRange { > type S = Comma; > } > >-impl<T> ToCss for Vec<T> where T: ToCss + OneOrMoreSeparated { >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+impl<T> ToCss for Vec<T> >+where >+ T: ToCss + OneOrMoreSeparated, >+{ >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > let mut iter = self.iter(); > iter.next().unwrap().to_css(dest)?; > for item in iter { > dest.write_str(<T as OneOrMoreSeparated>::S::separator())?; > item.to_css(dest)?; > } > Ok(()) > } > } > >-impl<T> ToCss for Box<T> where T: ?Sized + ToCss { >+impl<T> ToCss for Box<T> >+where >+ T: ?Sized + ToCss, >+{ > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >- where W: Write, >+ where >+ W: Write, > { > (**self).to_css(dest) > } > } > >-impl<T> ToCss for Arc<T> where T: ?Sized + ToCss { >+impl<T> ToCss for Arc<T> >+where >+ T: ?Sized + ToCss, >+{ > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >- where W: Write, >+ where >+ W: Write, > { > (**self).to_css(dest) > } > } > > impl ToCss for Au { >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > self.to_f64_px().to_css(dest)?; > dest.write_str("px") > } > } > > macro_rules! impl_to_css_for_predefined_type { > ($name: ty) => { > impl<'a> ToCss for $name { >- fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where W: Write { >+ fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >+ where >+ W: Write, >+ { > ::cssparser::ToCss::to_css(self, dest) > } > } > }; > } > > impl_to_css_for_predefined_type!(f32); > impl_to_css_for_predefined_type!(i8); >diff --git a/servo/components/style_traits/viewport.rs b/servo/components/style_traits/viewport.rs >index d961fa9e62ed..aeb4a75d53de 100644 >--- a/servo/components/style_traits/viewport.rs >+++ b/servo/components/style_traits/viewport.rs >@@ -1,18 +1,18 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > //! Helper types for the `@viewport` rule. > >-use {CSSPixel, CssWriter, ParseError, PinchZoomFactor, ToCss}; > use cssparser::Parser; > use euclid::TypedSize2D; > use std::fmt::{self, Write}; >+use {CSSPixel, CssWriter, ParseError, PinchZoomFactor, ToCss}; > > define_css_keyword_enum! { > pub enum UserZoom { > Zoom = "zoom", > Fixed = "fixed", > } > } > >@@ -23,32 +23,35 @@ define_css_keyword_enum! { > Landscape = "landscape", > } > } > > /// A set of viewport descriptors: > /// > /// <https://drafts.csswg.org/css-device-adapt/#viewport-desc> > #[derive(Clone, Debug, PartialEq)] >-#[cfg_attr(feature = "servo", derive(Deserialize, Serialize, MallocSizeOf))] >+#[cfg_attr( >+ feature = "servo", >+ derive(Deserialize, Serialize, MallocSizeOf) >+)] > pub struct ViewportConstraints { > /// Width and height: > /// * https://drafts.csswg.org/css-device-adapt/#width-desc > /// * https://drafts.csswg.org/css-device-adapt/#height-desc > pub size: TypedSize2D<f32, CSSPixel>, > /// <https://drafts.csswg.org/css-device-adapt/#zoom-desc> > pub initial_zoom: PinchZoomFactor, > /// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc> > pub min_zoom: Option<PinchZoomFactor>, > /// <https://drafts.csswg.org/css-device-adapt/#min-max-width-desc> > pub max_zoom: Option<PinchZoomFactor>, > /// <https://drafts.csswg.org/css-device-adapt/#user-zoom-desc> > pub user_zoom: UserZoom, > /// <https://drafts.csswg.org/css-device-adapt/#orientation-desc> >- pub orientation: Orientation >+ pub orientation: Orientation, > } > > impl ToCss for ViewportConstraints { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result > where > W: Write, > { > dest.write_str("@viewport { width: ")?; >@@ -88,17 +91,18 @@ pub enum Zoom { > /// A percentage value. > Percentage(f32), > /// The `auto` keyword. > Auto, > } > > impl ToCss for Zoom { > fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result >- where W: fmt::Write, >+ where >+ W: fmt::Write, > { > match *self { > Zoom::Number(number) => number.to_css(dest), > Zoom::Auto => dest.write_str("auto"), > Zoom::Percentage(percentage) => { > (percentage * 100.).to_css(dest)?; > dest.write_char('%') > } >@@ -106,42 +110,42 @@ impl ToCss for Zoom { > } > } > > impl Zoom { > /// Parse a zoom value per: > /// > /// <https://drafts.csswg.org/css-device-adapt/#descdef-viewport-zoom> > pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Zoom, ParseError<'i>> { >- use ParsingMode; > use cssparser::Token; > use values::specified::AllowedNumericType::NonNegative; >+ use ParsingMode; > > let location = input.current_source_location(); > match *input.next()? { > // TODO: This parse() method should take ParserContext as an > // argument, and pass ParsingMode owned by the ParserContext to > // is_ok() instead of using ParsingMode::DEFAULT directly. > // In order to do so, we might want to move these stuff into style::stylesheets::viewport_rule. >- Token::Percentage { unit_value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, unit_value) => { >+ Token::Percentage { unit_value, .. } >+ if NonNegative.is_ok(ParsingMode::DEFAULT, unit_value) => >+ { > Ok(Zoom::Percentage(unit_value)) > } > Token::Number { value, .. } if NonNegative.is_ok(ParsingMode::DEFAULT, value) => { > Ok(Zoom::Number(value)) > } >- Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => { >- Ok(Zoom::Auto) >- } >- ref t => Err(location.new_unexpected_token_error(t.clone())) >+ Token::Ident(ref value) if value.eq_ignore_ascii_case("auto") => Ok(Zoom::Auto), >+ ref t => Err(location.new_unexpected_token_error(t.clone())), > } > } > > /// Get this zoom value as a float value. Returns `None` if the value is the > /// `auto` keyword. > #[inline] > pub fn to_f32(&self) -> Option<f32> { > match *self { > Zoom::Number(number) => Some(number as f32), > Zoom::Percentage(percentage) => Some(percentage as f32), >- Zoom::Auto => None >+ Zoom::Auto => None, > } > } > } >diff --git a/testing/geckodriver/build.rs b/testing/geckodriver/build.rs >index 667e4559451e..82bc64df1dc1 100644 >--- a/testing/geckodriver/build.rs >+++ b/testing/geckodriver/build.rs >@@ -3,17 +3,16 @@ > /// > /// ```no_run > /// const COMMIT_HASH: Option<&'static str> = Some("c31a366"); > /// const COMMIT_DATE: Option<&'static str> = Some("1988-05-10"); > /// ``` > /// > /// The values are `None` if running hg failed, e.g. if it is not installed or > /// if we are not in an hg repo. >- > use std::env; > use std::ffi::OsStr; > use std::fs::File; > use std::io::Write; > use std::path::PathBuf; > use std::process::Command; > > fn main() { >@@ -27,21 +26,18 @@ fn main() { > writeln!( > fh, > "const COMMIT_DATE: Option<&'static str> = {:?};", > commit_date() > ).unwrap(); > } > > fn commit_hash() -> Option<String> { >- exec(&"hg", &["log", "-r.", "-T{node|short}"]).or_else( >- || { >- exec(&"git", &["rev-parse", "HEAD"]).and_then(hg2git_sha) >- }, >- ) >+ exec(&"hg", &["log", "-r.", "-T{node|short}"]) >+ .or_else(|| exec(&"git", &["rev-parse", "HEAD"]).and_then(hg2git_sha)) > } > > fn commit_date() -> Option<String> { > exec(&"hg", &["log", "-r.", "-T{date|isodate}"]).or_else(|| { > exec( > &"git", > &["log", "-1", "--date=short", "--pretty=format:%cd"], > ) >@@ -54,20 +50,21 @@ where > I: IntoIterator<Item = S>, > { > let mut cmd = Command::new(program); > for arg in args { > cmd.arg(arg.as_ref()); > } > cmd.output() > .ok() >- .and_then(|r| if r.status.success() { >- Some(r.stdout) >- } else { >- None >- }) >- .and_then(|o| String::from_utf8(o).ok()) >+ .and_then(|r| { >+ if r.status.success() { >+ Some(r.stdout) >+ } else { >+ None >+ } >+ }).and_then(|o| String::from_utf8(o).ok()) > .map(|s| s.trim_right().into()) > } > > fn hg2git_sha(hg_sha: String) -> Option<String> { > exec(&"git", &["cinnabar", "git2hg", &hg_sha]) > } >diff --git a/testing/geckodriver/src/build.rs b/testing/geckodriver/src/build.rs >index 3cefa4b770ca..2ece9258729b 100644 >--- a/testing/geckodriver/src/build.rs >+++ b/testing/geckodriver/src/build.rs >@@ -1,11 +1,11 @@ > use std::fmt; > >-use rustc_serialize::json::{Json}; >+use rustc_serialize::json::Json; > > include!(concat!(env!("OUT_DIR"), "/build-info.rs")); > > pub struct BuildInfo; > > impl BuildInfo { > pub fn version() -> &'static str { > crate_version!() >diff --git a/testing/geckodriver/src/capabilities.rs b/testing/geckodriver/src/capabilities.rs >index 0c4cd7314b6c..75954d4f3569 100644 >--- a/testing/geckodriver/src/capabilities.rs >+++ b/testing/geckodriver/src/capabilities.rs >@@ -6,19 +6,19 @@ use mozrunner::runner::platform::firefox_default_path; > use mozversion::{self, firefox_version, Version}; > use regex::bytes::Regex; > use rustc_serialize::base64::FromBase64; > use rustc_serialize::json::Json; > use std::collections::BTreeMap; > use std::default::Default; > use std::error::Error; > use std::fs; >+use std::io; > use std::io::BufWriter; > use std::io::Cursor; >-use std::io; > use std::path::{Path, PathBuf}; > use std::process::{Command, Stdio}; > use std::str::{self, FromStr}; > use webdriver::capabilities::{BrowserCapabilities, Capabilities}; > use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult}; > use zip; > > /// Provides matching of `moz:firefoxOptions` and resolution of which Firefox >@@ -29,17 +29,16 @@ use zip; > /// system Firefox installation or an override, for example given to the > /// `--binary` flag of geckodriver. > pub struct FirefoxCapabilities<'a> { > pub chosen_binary: Option<PathBuf>, > fallback_binary: Option<&'a PathBuf>, > version_cache: BTreeMap<PathBuf, String>, > } > >- > impl<'a> FirefoxCapabilities<'a> { > pub fn new(fallback_binary: Option<&'a PathBuf>) -> FirefoxCapabilities<'a> { > FirefoxCapabilities { > chosen_binary: None, > fallback_binary: fallback_binary, > version_cache: BTreeMap::new(), > } > } >@@ -64,52 +63,54 @@ impl<'a> FirefoxCapabilities<'a> { > .ok() > .and_then(|x| x.version_string) > .or_else(|| { > debug!("Trying to read firefox version from binary"); > self.version_from_binary(binary) > }); > if let Some(ref version) = rv { > debug!("Found version {}", version); >- self.version_cache >- .insert(binary.clone(), version.clone()); >+ self.version_cache.insert(binary.clone(), version.clone()); > } else { > debug!("Failed to get binary version"); > } > rv > } else { > None > } > } > > fn version_from_binary(&self, binary: &PathBuf) -> Option<String> { >- let version_regexp = Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp"); >+ let version_regexp = >+ Regex::new(r#"\d+\.\d+(?:[a-z]\d+)?"#).expect("Error parsing version regexp"); > let output = Command::new(binary) > .args(&["-version"]) > .stdout(Stdio::piped()) > .spawn() > .and_then(|child| child.wait_with_output()) > .ok(); > > if let Some(x) = output { >- version_regexp.captures(&*x.stdout) >+ version_regexp >+ .captures(&*x.stdout) > .and_then(|captures| captures.get(0)) > .and_then(|m| str::from_utf8(m.as_bytes()).ok()) > .map(|x| x.into()) > } else { > None > } > } > } > > // TODO: put this in webdriver-rust > fn convert_version_error(err: mozversion::Error) -> WebDriverError { > WebDriverError::new( > ErrorStatus::SessionNotCreated, >- err.description().to_string()) >+ err.description().to_string(), >+ ) > } > > impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> { > fn init(&mut self, capabilities: &Capabilities) { > self.set_binary(capabilities); > } > > fn browser_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> { >@@ -117,18 +118,18 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> { > } > > fn browser_version(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> { > Ok(self.version()) > } > > fn platform_name(&mut self, _: &Capabilities) -> WebDriverResult<Option<String>> { > Ok(if cfg!(target_os = "windows") { >- Some("windows".into()) >- } else if cfg!(target_os = "macos") { >+ Some("windows".into()) >+ } else if cfg!(target_os = "macos") { > Some("mac".into()) > } else if cfg!(target_os = "linux") { > Some("linux".into()) > } else { > None > }) > } > >@@ -140,120 +141,149 @@ impl<'a> BrowserCapabilities for FirefoxCapabilities<'a> { > Ok(false) > } > } > > fn set_window_rect(&mut self, _: &Capabilities) -> WebDriverResult<bool> { > Ok(true) > } > >- fn compare_browser_version(&mut self, >- version: &str, >- comparison: &str) >- -> WebDriverResult<bool> { >+ fn compare_browser_version( >+ &mut self, >+ version: &str, >+ comparison: &str, >+ ) -> WebDriverResult<bool> { > try!(Version::from_str(version).or_else(|x| Err(convert_version_error(x)))) > .matches(comparison) > .or_else(|x| Err(convert_version_error(x))) > } > > fn accept_proxy(&mut self, _: &Capabilities, _: &Capabilities) -> WebDriverResult<bool> { > Ok(true) > } > >- fn validate_custom(&self, name: &str, value: &Json) -> WebDriverResult<()> { >+ fn validate_custom(&self, name: &str, value: &Json) -> WebDriverResult<()> { > if !name.starts_with("moz:") { >- return Ok(()) >+ return Ok(()); > } > match name { > "moz:firefoxOptions" => { >- let data = try_opt!(value.as_object(), >- ErrorStatus::InvalidArgument, >- "moz:firefoxOptions is not an object"); >+ let data = try_opt!( >+ value.as_object(), >+ ErrorStatus::InvalidArgument, >+ "moz:firefoxOptions is not an object" >+ ); > for (key, value) in data.iter() { > match &**key { > "binary" => { > if !value.is_string() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "binary path is not a string")); >+ "binary path is not a string", >+ )); > } >- }, >+ } > "args" => { >- if !try_opt!(value.as_array(), >- ErrorStatus::InvalidArgument, >- "args is not an array") >- .iter() >- .all(|value| value.is_string()) { >+ if !try_opt!( >+ value.as_array(), >+ ErrorStatus::InvalidArgument, >+ "args is not an array" >+ ).iter() >+ .all(|value| value.is_string()) >+ { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "args entry is not a string")); >- } >- }, >+ "args entry is not a string", >+ )); >+ } >+ } > "profile" => { > if !value.is_string() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "profile is not a string")); >+ "profile is not a string", >+ )); > } >- }, >+ } > "log" => { >- let log_data = try_opt!(value.as_object(), >- ErrorStatus::InvalidArgument, >- "log value is not an object"); >+ let log_data = try_opt!( >+ value.as_object(), >+ ErrorStatus::InvalidArgument, >+ "log value is not an object" >+ ); > for (log_key, log_value) in log_data.iter() { > match &**log_key { > "level" => { >- let level = try_opt!(log_value.as_string(), >- ErrorStatus::InvalidArgument, >- "log level is not a string"); >+ let level = try_opt!( >+ log_value.as_string(), >+ ErrorStatus::InvalidArgument, >+ "log level is not a string" >+ ); > if Level::from_str(level).is_err() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- format!("Not a valid log level: {}", level))) >+ format!("Not a valid log level: {}", level), >+ )); > } > } >- x => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("Invalid log field {}", x))) >+ x => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Invalid log field {}", x), >+ )) >+ } > } > } >- }, >+ } > "prefs" => { >- let prefs_data = try_opt!(value.as_object(), >- ErrorStatus::InvalidArgument, >- "prefs value is not an object"); >- if !prefs_data.values() >- .all(|x| x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean()) { >- return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- "Preference values not all string or integer or boolean")); >- } >+ let prefs_data = try_opt!( >+ value.as_object(), >+ ErrorStatus::InvalidArgument, >+ "prefs value is not an object" >+ ); >+ if !prefs_data.values().all(|x| { >+ x.is_string() || x.is_i64() || x.is_u64() || x.is_boolean() >+ }) { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Preference values not all string or integer or boolean", >+ )); >+ } >+ } >+ x => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Invalid moz:firefoxOptions field {}", x), >+ )) > } >- x => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("Invalid moz:firefoxOptions field {}", x))) > } > } > } > "moz:useNonSpecCompliantPointerOrigin" => { > if !value.is_boolean() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "moz:useNonSpecCompliantPointerOrigin is not a boolean")); >+ "moz:useNonSpecCompliantPointerOrigin is not a boolean", >+ )); > } > } > "moz:webdriverClick" => { > if !value.is_boolean() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "moz:webdriverClick is not a boolean")); >+ "moz:webdriverClick is not a boolean", >+ )); > } > } >- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- format!("Unrecognised option {}", name))) >+ _ => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Unrecognised option {}", name), >+ )) >+ } > } > Ok(()) > } > > fn accept_custom(&mut self, _: &str, _: &Json, _: &Capabilities) -> WebDriverResult<bool> { > Ok(true) > } > } >@@ -273,75 +303,82 @@ pub struct FirefoxOptions { > pub prefs: Vec<(String, Pref)>, > } > > impl FirefoxOptions { > pub fn new() -> FirefoxOptions { > Default::default() > } > >- pub fn from_capabilities(binary_path: Option<PathBuf>, >- matched: &mut Capabilities) >- -> WebDriverResult<FirefoxOptions> { >+ pub fn from_capabilities( >+ binary_path: Option<PathBuf>, >+ matched: &mut Capabilities, >+ ) -> WebDriverResult<FirefoxOptions> { > let mut rv = FirefoxOptions::new(); > rv.binary = binary_path; > > if let Some(json) = matched.remove("moz:firefoxOptions") { >- let options = try!(json.as_object() >- .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument, >- "'moz:firefoxOptions' \ >- capability is not an object"))); >+ let options = try!(json.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "'moz:firefoxOptions' \ >+ capability is not an object" >+ ))); > > rv.profile = try!(FirefoxOptions::load_profile(&options)); > rv.args = try!(FirefoxOptions::load_args(&options)); > rv.log = try!(FirefoxOptions::load_log(&options)); > rv.prefs = try!(FirefoxOptions::load_prefs(&options)); > } > > Ok(rv) > } > > fn load_profile(options: &Capabilities) -> WebDriverResult<Option<Profile>> { > if let Some(profile_json) = options.get("profile") { >- let profile_base64 = >- try!(profile_json >- .as_string() >- .ok_or(WebDriverError::new(ErrorStatus::UnknownError, >- "Profile is not a string"))); >+ let profile_base64 = try!(profile_json.as_string().ok_or(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Profile is not a string" >+ ))); > let profile_zip = &*try!(profile_base64.from_base64()); > > // Create an emtpy profile directory > let profile = try!(Profile::new(None)); >- try!(unzip_buffer(profile_zip, >- profile >- .temp_dir >- .as_ref() >- .expect("Profile doesn't have a path") >- .path())); >+ try!(unzip_buffer( >+ profile_zip, >+ profile >+ .temp_dir >+ .as_ref() >+ .expect("Profile doesn't have a path") >+ .path() >+ )); > > Ok(Some(profile)) > } else { > Ok(None) > } > } > > fn load_args(options: &Capabilities) -> WebDriverResult<Option<Vec<String>>> { > if let Some(args_json) = options.get("args") { >- let args_array = try!(args_json >- .as_array() >- .ok_or(WebDriverError::new(ErrorStatus::UnknownError, >- "Arguments were not an \ >- array"))); >- let args = try!(args_array >- .iter() >- .map(|x| x.as_string().map(|x| x.to_owned())) >- .collect::<Option<Vec<String>>>() >- .ok_or(WebDriverError::new(ErrorStatus::UnknownError, >- "Arguments entries were not all \ >- strings"))); >+ let args_array = try!(args_json.as_array().ok_or(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Arguments were not an \ >+ array" >+ ))); >+ let args = try!( >+ args_array >+ .iter() >+ .map(|x| x.as_string().map(|x| x.to_owned())) >+ .collect::<Option<Vec<String>>>() >+ .ok_or(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Arguments entries were not all \ >+ strings" >+ )) >+ ); > Ok(Some(args)) > } else { > Ok(None) > } > } > > fn load_log(options: &Capabilities) -> WebDriverResult<LogOptions> { > if let Some(json) = options.get("log") { >@@ -367,20 +404,20 @@ impl FirefoxOptions { > Ok(LogOptions { level }) > } else { > Ok(Default::default()) > } > } > > pub fn load_prefs(options: &Capabilities) -> WebDriverResult<Vec<(String, Pref)>> { > if let Some(prefs_data) = options.get("prefs") { >- let prefs = try!(prefs_data >- .as_object() >- .ok_or(WebDriverError::new(ErrorStatus::UnknownError, >- "Prefs were not an object"))); >+ let prefs = try!(prefs_data.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Prefs were not an object" >+ ))); > let mut rv = Vec::with_capacity(prefs.len()); > for (key, value) in prefs.iter() { > rv.push((key.clone(), try!(pref_from_json(value)))); > } > Ok(rv) > } else { > Ok(vec![]) > } >@@ -388,31 +425,35 @@ impl FirefoxOptions { > } > > fn pref_from_json(value: &Json) -> WebDriverResult<Pref> { > match value { > &Json::String(ref x) => Ok(Pref::new(x.clone())), > &Json::I64(x) => Ok(Pref::new(x)), > &Json::U64(x) => Ok(Pref::new(x as i64)), > &Json::Boolean(x) => Ok(Pref::new(x)), >- _ => Err(WebDriverError::new(ErrorStatus::UnknownError, >- "Could not convert pref value to string, boolean, or integer")) >+ _ => Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Could not convert pref value to string, boolean, or integer", >+ )), > } > } > > fn unzip_buffer(buf: &[u8], dest_dir: &Path) -> WebDriverResult<()> { > let reader = Cursor::new(buf); >- let mut zip = try!(zip::ZipArchive::new(reader).map_err(|_| { >- WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile") >- })); >+ let mut zip = try!( >+ zip::ZipArchive::new(reader) >+ .map_err(|_| WebDriverError::new(ErrorStatus::UnknownError, "Failed to unzip profile")) >+ ); > > for i in 0..zip.len() { >- let mut file = try!(zip.by_index(i).map_err(|_| { >- WebDriverError::new(ErrorStatus::UnknownError, "Processing profile zip file failed") >- })); >+ let mut file = try!(zip.by_index(i).map_err(|_| WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Processing profile zip file failed" >+ ))); > let unzip_path = { > let name = file.name(); > let is_dir = name.ends_with("/"); > let rel_path = Path::new(name); > let dest_path = dest_dir.join(rel_path); > > { > let create_dir = if is_dir { >@@ -492,18 +533,20 @@ mod tests { > firefox_opts.insert("profile".into(), encoded_profile); > > let opts = make_options(firefox_opts); > let mut profile = opts.profile.unwrap(); > let prefs = profile.user_prefs().unwrap(); > > println!("{:#?}", prefs.prefs); > >- assert_eq!(prefs.get("startup.homepage_welcome_url"), >- Some(&Pref::new("data:text/html,PASS"))); >+ assert_eq!( >+ prefs.get("startup.homepage_welcome_url"), >+ Some(&Pref::new("data:text/html,PASS")) >+ ); > } > > #[test] > fn test_prefs() { > let encoded_profile = example_profile(); > let mut prefs: BTreeMap<String, Json> = BTreeMap::new(); > prefs.insert( > "browser.display.background_color".into(), >diff --git a/testing/geckodriver/src/logging.rs b/testing/geckodriver/src/logging.rs >index 4a4faa86923c..a8bda4da5c43 100644 >--- a/testing/geckodriver/src/logging.rs >+++ b/testing/geckodriver/src/logging.rs >@@ -274,17 +274,20 @@ mod tests { > (Level::Warn, "Warn"), > (Level::Info, "Info"), > (Level::Config, "Config"), > (Level::Debug, "Debug"), > (Level::Trace, "Trace"), > ]; > > for &(lvl, s) in tests.iter() { >- let expected = Pref { value: PrefValue::String(s.to_string()), sticky: false }; >+ let expected = Pref { >+ value: PrefValue::String(s.to_string()), >+ sticky: false, >+ }; > assert_eq!(Into::<Pref>::into(lvl), expected); > } > } > > #[test] > fn test_level_from_str() { > assert_eq!(Level::from_str("fatal"), Ok(Level::Fatal)); > assert_eq!(Level::from_str("error"), Ok(Level::Error)); >diff --git a/testing/geckodriver/src/main.rs b/testing/geckodriver/src/main.rs >index 934855cc55ae..55aac7ec7819 100644 >--- a/testing/geckodriver/src/main.rs >+++ b/testing/geckodriver/src/main.rs >@@ -5,46 +5,46 @@ extern crate clap; > extern crate lazy_static; > extern crate hyper; > extern crate mozprofile; > extern crate mozrunner; > extern crate mozversion; > extern crate regex; > extern crate rustc_serialize; > extern crate uuid; >-extern crate zip; > extern crate webdriver; >+extern crate zip; > > #[macro_use] > extern crate log; > > use std::io::Write; > use std::net::{IpAddr, SocketAddr}; > use std::path::PathBuf; > use std::str::FromStr; > > use clap::{App, Arg}; > > macro_rules! try_opt { >- ($expr:expr, $err_type:expr, $err_msg:expr) => ({ >+ ($expr:expr, $err_type:expr, $err_msg:expr) => {{ > match $expr { > Some(x) => x, >- None => return Err(WebDriverError::new($err_type, $err_msg)) >+ None => return Err(WebDriverError::new($err_type, $err_msg)), > } >- }) >+ }}; > } > > mod build; >+mod capabilities; > mod logging; >-mod prefs; > mod marionette; >-mod capabilities; >+mod prefs; > > use build::BuildInfo; >-use marionette::{MarionetteHandler, MarionetteSettings, extension_routes}; >+use marionette::{extension_routes, MarionetteHandler, MarionetteSettings}; > > type ProgramResult = std::result::Result<(), (ExitCode, String)>; > > enum ExitCode { > Ok = 0, > Usage = 64, > Unavailable = 69, > } >@@ -57,62 +57,72 @@ fn print_version() { > println!(""); > println!("This program is subject to the terms of the Mozilla Public License 2.0."); > println!("You can obtain a copy of the license at https://mozilla.org/MPL/2.0/."); > } > > fn app<'a, 'b>() -> App<'a, 'b> { > App::new(format!("geckodriver {}", crate_version!())) > .about("WebDriver implementation for Firefox.") >- .arg(Arg::with_name("webdriver_host") >- .long("host") >- .value_name("HOST") >- .help("Host ip to use for WebDriver server (default: 127.0.0.1)") >- .takes_value(true)) >- .arg(Arg::with_name("webdriver_port") >- .short("p") >- .long("port") >- .value_name("PORT") >- .help("Port to use for WebDriver server (default: 4444)") >- .takes_value(true) >- .alias("webdriver-port")) >- .arg(Arg::with_name("binary") >- .short("b") >- .long("binary") >- .value_name("BINARY") >- .help("Path to the Firefox binary") >- .takes_value(true)) >- .arg(Arg::with_name("marionette_port") >- .long("marionette-port") >- .value_name("PORT") >- .help("Port to use to connect to Gecko (default: random free port)") >- .takes_value(true)) >- .arg(Arg::with_name("connect_existing") >- .long("connect-existing") >- .requires("marionette_port") >- .help("Connect to an existing Firefox instance")) >- .arg(Arg::with_name("jsdebugger") >- .long("jsdebugger") >- .takes_value(false) >- .help("Attach browser toolbox debugger for Firefox")) >- .arg(Arg::with_name("verbosity") >- .short("v") >- .multiple(true) >- .conflicts_with("log_level") >- .help("Log level verbosity (-v for debug and -vv for trace level)")) >- .arg(Arg::with_name("log_level") >- .long("log") >- .takes_value(true) >- .value_name("LEVEL") >- .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"]) >- .help("Set Gecko log level")) >- .arg(Arg::with_name("version") >- .short("V") >- .long("version") >- .help("Prints version and copying information")) >+ .arg( >+ Arg::with_name("webdriver_host") >+ .long("host") >+ .value_name("HOST") >+ .help("Host ip to use for WebDriver server (default: 127.0.0.1)") >+ .takes_value(true), >+ ).arg( >+ Arg::with_name("webdriver_port") >+ .short("p") >+ .long("port") >+ .value_name("PORT") >+ .help("Port to use for WebDriver server (default: 4444)") >+ .takes_value(true) >+ .alias("webdriver-port"), >+ ).arg( >+ Arg::with_name("binary") >+ .short("b") >+ .long("binary") >+ .value_name("BINARY") >+ .help("Path to the Firefox binary") >+ .takes_value(true), >+ ).arg( >+ Arg::with_name("marionette_port") >+ .long("marionette-port") >+ .value_name("PORT") >+ .help("Port to use to connect to Gecko (default: random free port)") >+ .takes_value(true), >+ ).arg( >+ Arg::with_name("connect_existing") >+ .long("connect-existing") >+ .requires("marionette_port") >+ .help("Connect to an existing Firefox instance"), >+ ).arg( >+ Arg::with_name("jsdebugger") >+ .long("jsdebugger") >+ .takes_value(false) >+ .help("Attach browser toolbox debugger for Firefox"), >+ ).arg( >+ Arg::with_name("verbosity") >+ .short("v") >+ .multiple(true) >+ .conflicts_with("log_level") >+ .help("Log level verbosity (-v for debug and -vv for trace level)"), >+ ).arg( >+ Arg::with_name("log_level") >+ .long("log") >+ .takes_value(true) >+ .value_name("LEVEL") >+ .possible_values(&["fatal", "error", "warn", "info", "config", "debug", "trace"]) >+ .help("Set Gecko log level"), >+ ).arg( >+ Arg::with_name("version") >+ .short("V") >+ .long("version") >+ .help("Prints version and copying information"), >+ ) > } > > fn run() -> ProgramResult { > let matches = app().get_matches(); > > if matches.is_present("version") { > print_version(); > return Ok(()); >@@ -131,22 +141,20 @@ fn run() -> ProgramResult { > let addr = match IpAddr::from_str(host) { > Ok(addr) => SocketAddr::new(addr, port), > Err(_) => return Err((ExitCode::Usage, "invalid host address".into())), > }; > > let binary = matches.value_of("binary").map(|x| PathBuf::from(x)); > > let marionette_port = match matches.value_of("marionette_port") { >- Some(x) => { >- match u16::from_str(x) { >- Ok(x) => Some(x), >- Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())), >- } >- } >+ Some(x) => match u16::from_str(x) { >+ Ok(x) => Some(x), >+ Err(_) => return Err((ExitCode::Usage, "invalid Marionette port".into())), >+ }, > None => None, > }; > > let log_level = if matches.is_present("log_level") { > logging::Level::from_str(matches.value_of("log_level").unwrap()).ok() > } else { > match matches.occurrences_of("verbosity") { > 0 => Some(logging::Level::Info), >diff --git a/testing/geckodriver/src/marionette.rs b/testing/geckodriver/src/marionette.rs >index 695ca34df5de..0bd29ce217e2 100644 >--- a/testing/geckodriver/src/marionette.rs >+++ b/testing/geckodriver/src/marionette.rs >@@ -1,123 +1,148 @@ > use hyper::method::Method; > use mozprofile::preferences::Pref; > use mozprofile::profile::Profile; >-use mozrunner::runner::{FirefoxRunner, FirefoxProcess, Runner, RunnerProcess}; >+use mozrunner::runner::{FirefoxProcess, FirefoxRunner, Runner, RunnerProcess}; > use regex::Captures; > use rustc_serialize::base64::FromBase64; > use rustc_serialize::json; > use rustc_serialize::json::{Json, ToJson}; > use std::collections::BTreeMap; > use std::env; > use std::error::Error; > use std::fs::File; >+use std::io::prelude::*; > use std::io::Error as IoError; > use std::io::ErrorKind; >-use std::io::prelude::*; >-use std::path::PathBuf; > use std::io::Result as IoResult; > use std::net::{TcpListener, TcpStream}; >+use std::path::PathBuf; > use std::sync::Mutex; > use std::thread; > use std::time; > use uuid::Uuid; > use webdriver::capabilities::CapabilitiesMatching; >-use webdriver::command::{WebDriverCommand, WebDriverMessage, Parameters, >- WebDriverExtensionCommand}; > use webdriver::command::WebDriverCommand::{ >- NewSession, DeleteSession, Status, Get, GetCurrentUrl, >- GoBack, GoForward, Refresh, GetTitle, GetPageSource, GetWindowHandle, >- GetWindowHandles, CloseWindow, SetWindowRect, GetWindowRect, >- MinimizeWindow, MaximizeWindow, FullscreenWindow, SwitchToWindow, SwitchToFrame, >- SwitchToParentFrame, FindElement, FindElements, >- FindElementElement, FindElementElements, GetActiveElement, >- IsDisplayed, IsSelected, GetElementAttribute, GetElementProperty, GetCSSValue, >- GetElementText, GetElementTagName, GetElementRect, IsEnabled, >- ElementClick, ElementTap, ElementClear, ElementSendKeys, >- ExecuteScript, ExecuteAsyncScript, GetCookies, GetNamedCookie, AddCookie, >- DeleteCookies, DeleteCookie, GetTimeouts, SetTimeouts, DismissAlert, >- AcceptAlert, GetAlertText, SendAlertText, TakeScreenshot, TakeElementScreenshot, >- Extension, PerformActions, ReleaseActions}; >+ AcceptAlert, AddCookie, CloseWindow, DeleteCookie, DeleteCookies, DeleteSession, DismissAlert, >+ ElementClear, ElementClick, ElementSendKeys, ElementTap, ExecuteAsyncScript, ExecuteScript, >+ Extension, FindElement, FindElementElement, FindElementElements, FindElements, >+ FullscreenWindow, Get, GetActiveElement, GetAlertText, GetCSSValue, GetCookies, GetCurrentUrl, >+ GetElementAttribute, GetElementProperty, GetElementRect, GetElementTagName, GetElementText, >+ GetNamedCookie, GetPageSource, GetTimeouts, GetTitle, GetWindowHandle, GetWindowHandles, >+ GetWindowRect, GoBack, GoForward, IsDisplayed, IsEnabled, IsSelected, MaximizeWindow, >+ MinimizeWindow, NewSession, PerformActions, Refresh, ReleaseActions, SendAlertText, >+ SetTimeouts, SetWindowRect, Status, SwitchToFrame, SwitchToParentFrame, SwitchToWindow, >+ TakeElementScreenshot, TakeScreenshot, >+}; > use webdriver::command::{ >- NewSessionParameters, GetParameters, WindowRectParameters, SwitchToWindowParameters, >- SwitchToFrameParameters, LocatorParameters, JavascriptCommandParameters, >- GetNamedCookieParameters, AddCookieParameters, TimeoutsParameters, >- ActionsParameters, TakeScreenshotParameters}; >-use webdriver::response::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, >- ElementRectResponse, NewSessionResponse, TimeoutsResponse, >- ValueResponse, WebDriverResponse, WindowRectResponse}; >-use webdriver::common::{Date, ELEMENT_KEY, FrameId, FRAME_KEY, Nullable, WebElement, WINDOW_KEY}; >+ ActionsParameters, AddCookieParameters, GetNamedCookieParameters, GetParameters, >+ JavascriptCommandParameters, LocatorParameters, NewSessionParameters, SwitchToFrameParameters, >+ SwitchToWindowParameters, TakeScreenshotParameters, TimeoutsParameters, WindowRectParameters, >+}; >+use webdriver::command::{ >+ Parameters, WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage, >+}; >+use webdriver::common::{Date, FrameId, Nullable, WebElement, ELEMENT_KEY, FRAME_KEY, WINDOW_KEY}; > use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult}; >-use webdriver::server::{WebDriverHandler, Session}; >-use webdriver::httpapi::{WebDriverExtensionRoute}; >+use webdriver::httpapi::WebDriverExtensionRoute; >+use webdriver::response::{ >+ CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, ElementRectResponse, >+ NewSessionResponse, TimeoutsResponse, ValueResponse, WebDriverResponse, WindowRectResponse, >+}; >+use webdriver::server::{Session, WebDriverHandler}; > > use build::BuildInfo; > use capabilities::{FirefoxCapabilities, FirefoxOptions}; > use logging; > use prefs; > > // localhost may be routed to the IPv6 stack on certain systems, > // and nsIServerSocket in Marionette only supports IPv4 > const DEFAULT_HOST: &'static str = "127.0.0.1"; > > const CHROME_ELEMENT_KEY: &'static str = "chromeelement-9fc5-4b51-a3c8-01716eedeb04"; > const LEGACY_ELEMENT_KEY: &'static str = "ELEMENT"; > > pub fn extension_routes() -> Vec<(Method, &'static str, GeckoExtensionRoute)> { >- return vec![(Method::Get, "/session/{sessionId}/moz/context", GeckoExtensionRoute::GetContext), >- (Method::Post, "/session/{sessionId}/moz/context", GeckoExtensionRoute::SetContext), >- (Method::Post, >- "/session/{sessionId}/moz/xbl/{elementId}/anonymous_children", >- GeckoExtensionRoute::XblAnonymousChildren), >- (Method::Post, >- "/session/{sessionId}/moz/xbl/{elementId}/anonymous_by_attribute", >- GeckoExtensionRoute::XblAnonymousByAttribute), >- (Method::Post, "/session/{sessionId}/moz/addon/install", >- GeckoExtensionRoute::InstallAddon), >- (Method::Post, "/session/{sessionId}/moz/addon/uninstall", >- GeckoExtensionRoute::UninstallAddon)]; >+ return vec![ >+ ( >+ Method::Get, >+ "/session/{sessionId}/moz/context", >+ GeckoExtensionRoute::GetContext, >+ ), >+ ( >+ Method::Post, >+ "/session/{sessionId}/moz/context", >+ GeckoExtensionRoute::SetContext, >+ ), >+ ( >+ Method::Post, >+ "/session/{sessionId}/moz/xbl/{elementId}/anonymous_children", >+ GeckoExtensionRoute::XblAnonymousChildren, >+ ), >+ ( >+ Method::Post, >+ "/session/{sessionId}/moz/xbl/{elementId}/anonymous_by_attribute", >+ GeckoExtensionRoute::XblAnonymousByAttribute, >+ ), >+ ( >+ Method::Post, >+ "/session/{sessionId}/moz/addon/install", >+ GeckoExtensionRoute::InstallAddon, >+ ), >+ ( >+ Method::Post, >+ "/session/{sessionId}/moz/addon/uninstall", >+ GeckoExtensionRoute::UninstallAddon, >+ ), >+ ]; > } > > #[derive(Clone, PartialEq)] > pub enum GeckoExtensionRoute { > GetContext, > SetContext, > XblAnonymousChildren, > XblAnonymousByAttribute, > InstallAddon, > UninstallAddon, > } > > impl WebDriverExtensionRoute for GeckoExtensionRoute { > type Command = GeckoExtensionCommand; > >- fn command(&self, >- captures: &Captures, >- body_data: &Json) >- -> WebDriverResult<WebDriverCommand<GeckoExtensionCommand>> { >+ fn command( >+ &self, >+ captures: &Captures, >+ body_data: &Json, >+ ) -> WebDriverResult<WebDriverCommand<GeckoExtensionCommand>> { > let command = match self { > &GeckoExtensionRoute::GetContext => GeckoExtensionCommand::GetContext, > &GeckoExtensionRoute::SetContext => { > let parameters: GeckoContextParameters = try!(Parameters::from_json(&body_data)); > GeckoExtensionCommand::SetContext(parameters) > } > &GeckoExtensionRoute::XblAnonymousChildren => { >- let element_id = try!(captures.name("elementId") >- .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Missing elementId parameter"))); >+ let element_id = try!(captures.name("elementId").ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ))); > GeckoExtensionCommand::XblAnonymousChildren(element_id.as_str().into()) > } > &GeckoExtensionRoute::XblAnonymousByAttribute => { >- let element_id = try!(captures.name("elementId") >- .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Missing elementId parameter"))); >+ let element_id = try!(captures.name("elementId").ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ))); > let parameters: AttributeParameters = try!(Parameters::from_json(&body_data)); >- GeckoExtensionCommand::XblAnonymousByAttribute(element_id.as_str().into(), >- parameters) >+ GeckoExtensionCommand::XblAnonymousByAttribute( >+ element_id.as_str().into(), >+ parameters, >+ ) > } > &GeckoExtensionRoute::InstallAddon => { > let parameters: AddonInstallParameters = try!(Parameters::from_json(&body_data)); > GeckoExtensionCommand::InstallAddon(parameters) > } > &GeckoExtensionRoute::UninstallAddon => { > let parameters: AddonUninstallParameters = try!(Parameters::from_json(&body_data)); > GeckoExtensionCommand::UninstallAddon(parameters) >@@ -129,17 +154,17 @@ impl WebDriverExtensionRoute for GeckoExtensionRoute { > > #[derive(Clone, PartialEq)] > pub enum GeckoExtensionCommand { > GetContext, > SetContext(GeckoContextParameters), > XblAnonymousChildren(WebElement), > XblAnonymousByAttribute(WebElement, AttributeParameters), > InstallAddon(AddonInstallParameters), >- UninstallAddon(AddonUninstallParameters) >+ UninstallAddon(AddonUninstallParameters), > } > > impl WebDriverExtensionCommand for GeckoExtensionCommand { > fn parameters_json(&self) -> Option<Json> { > match self { > &GeckoExtensionCommand::GetContext => None, > &GeckoExtensionCommand::SetContext(ref x) => Some(x.to_json()), > &GeckoExtensionCommand::XblAnonymousChildren(_) => None, >@@ -162,41 +187,42 @@ impl ToJson for GeckoContext { > &GeckoContext::Content => Json::String("content".to_owned()), > &GeckoContext::Chrome => Json::String("chrome".to_owned()), > } > } > } > > #[derive(Clone, Debug, PartialEq)] > pub struct GeckoContextParameters { >- context: GeckoContext >+ context: GeckoContext, > } > > impl Parameters for GeckoContextParameters { > fn from_json(body: &Json) -> WebDriverResult<GeckoContextParameters> { >- let data = try!(body.as_object().ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Message body was not an object"))); >- let context_value = try!(data.get("context").ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Missing context key"))); >- let value = try!(context_value.as_string().ok_or( >- WebDriverError::new( >- ErrorStatus::InvalidArgument, >- "context was not a string"))); >+ let data = try!(body.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ))); >+ let context_value = try!(data.get("context").ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Missing context key" >+ ))); >+ let value = try!(context_value.as_string().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "context was not a string" >+ ))); > let context = try!(match value { > "chrome" => Ok(GeckoContext::Chrome), > "content" => Ok(GeckoContext::Content), >- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- format!("{} is not a valid context", >- value))) >+ _ => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("{} is not a valid context", value) >+ )), > }); >- Ok(GeckoContextParameters { >- context: context >- }) >+ Ok(GeckoContextParameters { context: context }) > } > } > > impl ToMarionette for GeckoContextParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut data = BTreeMap::new(); > data.insert("value".to_owned(), self.context.to_json()); > Ok(data) >@@ -206,38 +232,48 @@ impl ToMarionette for GeckoContextParameters { > impl ToJson for GeckoContextParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("context".to_owned(), self.context.to_json()); > Json::Object(data) > } > } > >- > #[derive(Clone, Debug, PartialEq)] > pub struct AttributeParameters { > name: String, >- value: String >+ value: String, > } > > impl Parameters for AttributeParameters { > fn from_json(body: &Json) -> WebDriverResult<AttributeParameters> { >- let data = try!(body.as_object().ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Message body was not an object"))); >- let name = try!(try!(data.get("name").ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Missing 'name' parameter"))).as_string(). >- ok_or(WebDriverError::new(ErrorStatus::InvalidArgument, >- "'name' parameter is not a string"))); >- let value = try!(try!(data.get("value").ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Missing 'value' parameter"))).as_string(). >- ok_or(WebDriverError::new(ErrorStatus::InvalidArgument, >- "'value' parameter is not a string"))); >+ let data = try!(body.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ))); >+ let name = try!( >+ try!(data.get("name").ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Missing 'name' parameter" >+ ))).as_string() >+ .ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "'name' parameter is not a string" >+ )) >+ ); >+ let value = try!( >+ try!(data.get("value").ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Missing 'value' parameter" >+ ))).as_string() >+ .ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "'value' parameter is not a string" >+ )) >+ ); > Ok(AttributeParameters { > name: name.to_owned(), > value: value.to_owned(), > }) > } > } > > impl ToJson for AttributeParameters { >@@ -258,66 +294,81 @@ impl ToMarionette for AttributeParameters { > data.insert("value".to_owned(), Json::Object(value)); > Ok(data) > } > } > > #[derive(Clone, Debug, PartialEq)] > pub struct AddonInstallParameters { > pub path: String, >- pub temporary: bool >+ pub temporary: bool, > } > > impl Parameters for AddonInstallParameters { > fn from_json(body: &Json) -> WebDriverResult<AddonInstallParameters> { >- let data = try!(body.as_object().ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Message body was not an object"))); >+ let data = try!(body.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ))); > > let base64 = match data.get("addon") { > Some(x) => { >- let s = try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "'addon' is not a string").to_string(); >+ let s = try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "'addon' is not a string" >+ ).to_string(); > >- let addon_path = env::temp_dir().as_path() >+ let addon_path = env::temp_dir() >+ .as_path() > .join(format!("addon-{}.xpi", Uuid::new_v4())); > let mut addon_file = try!(File::create(&addon_path)); > let addon_buf = try!(s.from_base64()); > try!(addon_file.write(addon_buf.as_slice())); > >- Some(try_opt!(addon_path.to_str(), >- ErrorStatus::UnknownError, >- "could not write addon to file").to_string()) >- }, >+ Some( >+ try_opt!( >+ addon_path.to_str(), >+ ErrorStatus::UnknownError, >+ "could not write addon to file" >+ ).to_string(), >+ ) >+ } > None => None, > }; > let path = match data.get("path") { >- Some(x) => Some(try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "'path' is not a string").to_string()), >+ Some(x) => Some( >+ try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "'path' is not a string" >+ ).to_string(), >+ ), > None => None, > }; > if (base64.is_none() && path.is_none()) || (base64.is_some() && path.is_some()) { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Must specify exactly one of 'path' and 'addon'")); >+ "Must specify exactly one of 'path' and 'addon'", >+ )); > } > > let temporary = match data.get("temporary") { >- Some(x) => try_opt!(x.as_boolean(), >- ErrorStatus::InvalidArgument, >- "Failed to convert 'temporary' to boolean"), >- None => false >+ Some(x) => try_opt!( >+ x.as_boolean(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert 'temporary' to boolean" >+ ), >+ None => false, > }; > > return Ok(AddonInstallParameters { > path: base64.or(path).unwrap(), > temporary: temporary, >- }) >+ }); > } > } > > impl ToJson for AddonInstallParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("path".to_string(), self.path.to_json()); > data.insert("temporary".to_string(), self.temporary.to_json()); >@@ -331,33 +382,37 @@ impl ToMarionette for AddonInstallParameters { > data.insert("path".to_string(), self.path.to_json()); > data.insert("temporary".to_string(), self.temporary.to_json()); > Ok(data) > } > } > > #[derive(Clone, Debug, PartialEq)] > pub struct AddonUninstallParameters { >- pub id: String >+ pub id: String, > } > > impl Parameters for AddonUninstallParameters { > fn from_json(body: &Json) -> WebDriverResult<AddonUninstallParameters> { >- let data = try!(body.as_object().ok_or( >- WebDriverError::new(ErrorStatus::InvalidArgument, >- "Message body was not an object"))); >+ let data = try!(body.as_object().ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ))); > > let id = try_opt!( >- try_opt!(data.get("id"), >- ErrorStatus::InvalidArgument, >- "Missing 'id' parameter").as_string(), >+ try_opt!( >+ data.get("id"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'id' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "'id' is not a string").to_string(); >+ "'id' is not a string" >+ ).to_string(); > >- return Ok(AddonUninstallParameters {id: id}) >+ return Ok(AddonUninstallParameters { id: id }); > } > } > > impl ToJson for AddonUninstallParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("id".to_string(), self.id.to_json()); > Json::Object(data) >@@ -398,31 +453,36 @@ impl MarionetteHandler { > pub fn new(settings: MarionetteSettings) -> MarionetteHandler { > MarionetteHandler { > connection: Mutex::new(None), > settings, > browser: None, > } > } > >- fn create_connection(&mut self, >- session_id: &Option<String>, >- new_session_parameters: &NewSessionParameters) >- -> WebDriverResult<BTreeMap<String, Json>> { >+ fn create_connection( >+ &mut self, >+ session_id: &Option<String>, >+ new_session_parameters: &NewSessionParameters, >+ ) -> WebDriverResult<BTreeMap<String, Json>> { > let (options, capabilities) = { > let mut fx_capabilities = FirefoxCapabilities::new(self.settings.binary.as_ref()); > let mut capabilities = try!( >- try!(new_session_parameters >- .match_browser(&mut fx_capabilities)) >- .ok_or(WebDriverError::new( >+ try!(new_session_parameters.match_browser(&mut fx_capabilities)).ok_or( >+ WebDriverError::new( > ErrorStatus::SessionNotCreated, >- "Unable to find a matching set of capabilities"))); >+ "Unable to find a matching set of capabilities" >+ ) >+ ) >+ ); > >- let options = try!(FirefoxOptions::from_capabilities(fx_capabilities.chosen_binary, >- &mut capabilities)); >+ let options = try!(FirefoxOptions::from_capabilities( >+ fx_capabilities.chosen_binary, >+ &mut capabilities >+ )); > (options, capabilities) > }; > > if let Some(l) = options.log.level { > logging::set_max_level(l); > } > > let port = self.settings.port.unwrap_or(get_free_port()?); >@@ -433,34 +493,37 @@ impl MarionetteHandler { > let mut connection = MarionetteConnection::new(port, session_id.clone()); > try!(connection.connect(&mut self.browser)); > self.connection = Mutex::new(Some(connection)); > > Ok(capabilities) > } > > fn start_browser(&mut self, port: u16, options: FirefoxOptions) -> WebDriverResult<()> { >- let binary = options.binary >- .ok_or(WebDriverError::new(ErrorStatus::SessionNotCreated, >- "Expected browser binary location, but unable to find \ >- binary in default location, no \ >- 'moz:firefoxOptions.binary' capability provided, and \ >- no binary flag set on the command line"))?; >+ let binary = options.binary.ok_or(WebDriverError::new( >+ ErrorStatus::SessionNotCreated, >+ "Expected browser binary location, but unable to find \ >+ binary in default location, no \ >+ 'moz:firefoxOptions.binary' capability provided, and \ >+ no binary flag set on the command line", >+ ))?; > > let is_custom_profile = options.profile.is_some(); > > let mut profile = match options.profile { > Some(x) => x, >- None => Profile::new(None)? >+ None => Profile::new(None)?, > }; > > self.set_prefs(port, &mut profile, is_custom_profile, options.prefs) > .map_err(|e| { >- WebDriverError::new(ErrorStatus::SessionNotCreated, >- format!("Failed to set preferences: {}", e)) >+ WebDriverError::new( >+ ErrorStatus::SessionNotCreated, >+ format!("Failed to set preferences: {}", e), >+ ) > })?; > > let mut runner = FirefoxRunner::new(&binary, profile); > > // https://developer.mozilla.org/docs/Environment_variables_affecting_crash_reporting > runner > .env("MOZ_CRASHREPORTER", "1") > .env("MOZ_CRASHREPORTER_NO_REPORT", "1") >@@ -470,22 +533,22 @@ impl MarionetteHandler { > runner.arg("-marionette"); > if self.settings.jsdebugger { > runner.arg("-jsdebugger"); > } > if let Some(args) = options.args.as_ref() { > runner.args(args); > } > >- let browser_proc = runner.start() >- .map_err(|e| { >- WebDriverError::new(ErrorStatus::SessionNotCreated, >- format!("Failed to start browser {}: {}", >- binary.display(), e)) >- })?; >+ let browser_proc = runner.start().map_err(|e| { >+ WebDriverError::new( >+ ErrorStatus::SessionNotCreated, >+ format!("Failed to start browser {}: {}", binary.display(), e), >+ ) >+ })?; > self.browser = Some(browser_proc); > > Ok(()) > } > > pub fn set_prefs( > &self, > port: u16, >@@ -504,100 +567,113 @@ impl MarionetteHandler { > if !custom_profile || !prefs.contains_key(name) { > prefs.insert((*name).clone(), (*value).clone()); > } > } > > prefs.insert_slice(&extra_prefs[..]); > > if self.settings.jsdebugger { >- prefs.insert("devtools.browsertoolbox.panel", Pref::new("jsdebugger".to_owned())); >+ prefs.insert( >+ "devtools.browsertoolbox.panel", >+ Pref::new("jsdebugger".to_owned()), >+ ); > prefs.insert("devtools.debugger.remote-enabled", Pref::new(true)); > prefs.insert("devtools.chrome.enabled", Pref::new(true)); > prefs.insert("devtools.debugger.prompt-connection", Pref::new(false)); > prefs.insert("marionette.debugging.clicktostart", Pref::new(true)); > } > > prefs.insert("marionette.log.level", logging::max_level().into()); > prefs.insert("marionette.port", Pref::new(port)); > > prefs.write().map_err(|_| { > WebDriverError::new(ErrorStatus::UnknownError, "Unable to write Firefox profile") > }) > } > } > > impl WebDriverHandler<GeckoExtensionRoute> for MarionetteHandler { >- fn handle_command(&mut self, _: &Option<Session>, >- msg: WebDriverMessage<GeckoExtensionRoute>) -> WebDriverResult<WebDriverResponse> { >+ fn handle_command( >+ &mut self, >+ _: &Option<Session>, >+ msg: WebDriverMessage<GeckoExtensionRoute>, >+ ) -> WebDriverResult<WebDriverResponse> { > let mut resolved_capabilities = None; > { > let mut capabilities_options = None; > // First handle the status message which doesn't actually require a marionette > // connection or message > if msg.command == Status { >- let (ready, message) = self.connection.lock() >- .map(|ref connection| connection >- .as_ref() >- .map(|_| (false, "Session already started")) >- .unwrap_or((true, ""))) >- .unwrap_or((false, "geckodriver internal error")); >+ let (ready, message) = self >+ .connection >+ .lock() >+ .map(|ref connection| { >+ connection >+ .as_ref() >+ .map(|_| (false, "Session already started")) >+ .unwrap_or((true, "")) >+ }).unwrap_or((false, "geckodriver internal error")); > let mut value = BTreeMap::new(); > value.insert("ready".to_string(), Json::Boolean(ready)); > value.insert("message".to_string(), Json::String(message.into())); >- return Ok(WebDriverResponse::Generic(ValueResponse::new(Json::Object(value)))); >+ return Ok(WebDriverResponse::Generic(ValueResponse::new( >+ Json::Object(value), >+ ))); > } > match self.connection.lock() { > Ok(ref connection) => { > if connection.is_none() { > match msg.command { > NewSession(ref capabilities) => { > capabilities_options = Some(capabilities); >- }, >+ } > _ => { > return Err(WebDriverError::new( > ErrorStatus::SessionNotCreated, >- "Tried to run command without establishing a connection")); >+ "Tried to run command without establishing a connection", >+ )); > } > } > } >- }, >+ } > Err(_) => { > return Err(WebDriverError::new( > ErrorStatus::UnknownError, >- "Failed to aquire Marionette connection")) >+ "Failed to aquire Marionette connection", >+ )) > } > } > if let Some(capabilities) = capabilities_options { >- resolved_capabilities = Some(try!( >- self.create_connection(&msg.session_id, &capabilities))); >+ resolved_capabilities = >+ Some(try!(self.create_connection(&msg.session_id, &capabilities))); > } > } > > match self.connection.lock() { > Ok(ref mut connection) => { > match connection.as_mut() { > Some(conn) => { > conn.send_command(resolved_capabilities, &msg) > .map_err(|mut err| { > // Shutdown the browser if no session can > // be established due to errors. > if let NewSession(_) = msg.command { > err.delete_session = true; > } >- err}) >- }, >- None => panic!("Connection missing") >+ err >+ }) >+ } >+ None => panic!("Connection missing"), > } >- }, >- Err(_) => { >- Err(WebDriverError::new( >- ErrorStatus::UnknownError, >- "Failed to aquire Marionette connection")) > } >+ Err(_) => Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Failed to aquire Marionette connection", >+ )), > } > } > > fn delete_session(&mut self, session: &Option<Session>) { > if let Some(ref s) = *session { > let delete_session = WebDriverMessage { > session_id: Some(s.id.clone()), > command: WebDriverCommand::DeleteSession, >@@ -624,42 +700,48 @@ impl WebDriverHandler<GeckoExtensionRoute> for MarionetteHandler { > self.browser = None; > } > } > > pub struct MarionetteSession { > pub session_id: String, > protocol: Option<String>, > application_type: Option<String>, >- command_id: u64 >+ command_id: u64, > } > > impl MarionetteSession { > pub fn new(session_id: Option<String>) -> MarionetteSession { > let initital_id = session_id.unwrap_or("".to_string()); > MarionetteSession { > session_id: initital_id, > protocol: None, > application_type: None, >- command_id: 0 >+ command_id: 0, > } > } > >- pub fn update(&mut self, msg: &WebDriverMessage<GeckoExtensionRoute>, >- resp: &MarionetteResponse) -> WebDriverResult<()> { >+ pub fn update( >+ &mut self, >+ msg: &WebDriverMessage<GeckoExtensionRoute>, >+ resp: &MarionetteResponse, >+ ) -> WebDriverResult<()> { > match msg.command { > NewSession(_) => { > let session_id = try_opt!( >- try_opt!(resp.result.find("sessionId"), >- ErrorStatus::SessionNotCreated, >- "Unable to get session id").as_string(), >+ try_opt!( >+ resp.result.find("sessionId"), > ErrorStatus::SessionNotCreated, >- "Unable to convert session id to string"); >+ "Unable to get session id" >+ ).as_string(), >+ ErrorStatus::SessionNotCreated, >+ "Unable to convert session id to string" >+ ); > self.session_id = session_id.to_string().clone(); >- }, >+ } > _ => {} > } > Ok(()) > } > > /// Converts a Marionette JSON response into a `WebElement`. > /// > /// Note that it currently coerces all chrome elements, web frames, and web >@@ -694,347 +776,461 @@ impl MarionetteSession { > Ok(WebElement::new(id)) > } > > pub fn next_command_id(&mut self) -> u64 { > self.command_id = self.command_id + 1; > self.command_id > } > >- pub fn response(&mut self, msg: &WebDriverMessage<GeckoExtensionRoute>, >- resp: MarionetteResponse) -> WebDriverResult<WebDriverResponse> { >- >+ pub fn response( >+ &mut self, >+ msg: &WebDriverMessage<GeckoExtensionRoute>, >+ resp: MarionetteResponse, >+ ) -> WebDriverResult<WebDriverResponse> { > if resp.id != self.command_id { >- return Err(WebDriverError::new(ErrorStatus::UnknownError, >- format!("Marionette responses arrived out of sequence, expected {}, got {}", >- self.command_id, resp.id))); >+ return Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ format!( >+ "Marionette responses arrived out of sequence, expected {}, got {}", >+ self.command_id, resp.id >+ ), >+ )); > } > > if let Some(error) = resp.error { > return Err(error.into()); > } > > try!(self.update(msg, &resp)); > > Ok(match msg.command { > // Everything that doesn't have a response value >- Get(_) | GoBack | GoForward | Refresh | SetTimeouts(_) | >- SwitchToWindow(_) | SwitchToFrame(_) | >- SwitchToParentFrame | AddCookie(_) | DeleteCookies | DeleteCookie(_) | >- DismissAlert | AcceptAlert | SendAlertText(_) | ElementClick(_) | >- ElementTap(_) | ElementClear(_) | ElementSendKeys(_, _) | >- PerformActions(_) | ReleaseActions => { >- WebDriverResponse::Void >- }, >+ Get(_) >+ | GoBack >+ | GoForward >+ | Refresh >+ | SetTimeouts(_) >+ | SwitchToWindow(_) >+ | SwitchToFrame(_) >+ | SwitchToParentFrame >+ | AddCookie(_) >+ | DeleteCookies >+ | DeleteCookie(_) >+ | DismissAlert >+ | AcceptAlert >+ | SendAlertText(_) >+ | ElementClick(_) >+ | ElementTap(_) >+ | ElementClear(_) >+ | ElementSendKeys(_, _) >+ | PerformActions(_) >+ | ReleaseActions => WebDriverResponse::Void, > // Things that simply return the contents of the marionette "value" property >- GetCurrentUrl | GetTitle | GetPageSource | GetWindowHandle | IsDisplayed(_) | >- IsSelected(_) | GetElementAttribute(_, _) | GetElementProperty(_, _) | >- GetCSSValue(_, _) | GetElementText(_) | >- GetElementTagName(_) | IsEnabled(_) | ExecuteScript(_) | ExecuteAsyncScript(_) | >- GetAlertText | TakeScreenshot | TakeElementScreenshot(_) => { >- let value = try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, >- "Failed to find value field"); >+ GetCurrentUrl >+ | GetTitle >+ | GetPageSource >+ | GetWindowHandle >+ | IsDisplayed(_) >+ | IsSelected(_) >+ | GetElementAttribute(_, _) >+ | GetElementProperty(_, _) >+ | GetCSSValue(_, _) >+ | GetElementText(_) >+ | GetElementTagName(_) >+ | IsEnabled(_) >+ | ExecuteScript(_) >+ | ExecuteAsyncScript(_) >+ | GetAlertText >+ | TakeScreenshot >+ | TakeElementScreenshot(_) => { >+ let value = try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ); > //TODO: Convert webelement keys > WebDriverResponse::Generic(ValueResponse::new(value.clone())) >- }, >+ } > GetTimeouts => { >- let script = try_opt!(try_opt!(resp.result >- .find("script"), >- ErrorStatus::UnknownError, >- "Missing field: script") >- .as_u64(), >- ErrorStatus::UnknownError, >- "Failed to interpret script timeout duration as u64"); >+ let script = try_opt!( >+ try_opt!( >+ resp.result.find("script"), >+ ErrorStatus::UnknownError, >+ "Missing field: script" >+ ).as_u64(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret script timeout duration as u64" >+ ); > // Check for the spec-compliant "pageLoad", but also for "page load", > // which was sent by Firefox 52 and earlier. >- let page_load = try_opt!(try_opt!(resp.result.find("pageLoad") >- .or(resp.result.find("page load")), >- ErrorStatus::UnknownError, >- "Missing field: pageLoad") >- .as_u64(), >- ErrorStatus::UnknownError, >- "Failed to interpret page load duration as u64"); >- let implicit = try_opt!(try_opt!(resp.result >- .find("implicit"), >- ErrorStatus::UnknownError, >- "Missing field: implicit") >- .as_u64(), >- ErrorStatus::UnknownError, >- "Failed to interpret implicit search duration as u64"); >+ let page_load = try_opt!( >+ try_opt!( >+ resp.result >+ .find("pageLoad") >+ .or(resp.result.find("page load")), >+ ErrorStatus::UnknownError, >+ "Missing field: pageLoad" >+ ).as_u64(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret page load duration as u64" >+ ); >+ let implicit = try_opt!( >+ try_opt!( >+ resp.result.find("implicit"), >+ ErrorStatus::UnknownError, >+ "Missing field: implicit" >+ ).as_u64(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret implicit search duration as u64" >+ ); > > WebDriverResponse::Timeouts(TimeoutsResponse { > script: script, > pageLoad: page_load, > implicit: implicit, > }) >- }, >+ } > Status => panic!("Got status command that should already have been handled"), >- GetWindowHandles => { >- WebDriverResponse::Generic(ValueResponse::new(resp.result.clone())) >- }, >+ GetWindowHandles => WebDriverResponse::Generic(ValueResponse::new(resp.result.clone())), > CloseWindow => { >- let data = try_opt!(resp.result.as_array(), >- ErrorStatus::UnknownError, >- "Failed to interpret value as array"); >- let handles = try!(data.iter() >- .map(|x| { >- Ok(try_opt!(x.as_string(), >- ErrorStatus::UnknownError, >- "Failed to interpret window handle as string") >- .to_owned()) >- }) >- .collect()); >- WebDriverResponse::CloseWindow(CloseWindowResponse { window_handles: handles }) >- }, >+ let data = try_opt!( >+ resp.result.as_array(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret value as array" >+ ); >+ let handles = try!( >+ data.iter() >+ .map(|x| Ok(try_opt!( >+ x.as_string(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret window handle as string" >+ ).to_owned())).collect() >+ ); >+ WebDriverResponse::CloseWindow(CloseWindowResponse { >+ window_handles: handles, >+ }) >+ } > GetElementRect(_) => { > let x = try_opt!( >- try_opt!(resp.result.find("x"), >- ErrorStatus::UnknownError, >- "Failed to find x field").as_f64(), >+ try_opt!( >+ resp.result.find("x"), >+ ErrorStatus::UnknownError, >+ "Failed to find x field" >+ ).as_f64(), > ErrorStatus::UnknownError, >- "Failed to interpret x as float"); >+ "Failed to interpret x as float" >+ ); > > let y = try_opt!( >- try_opt!(resp.result.find("y"), >- ErrorStatus::UnknownError, >- "Failed to find y field").as_f64(), >+ try_opt!( >+ resp.result.find("y"), >+ ErrorStatus::UnknownError, >+ "Failed to find y field" >+ ).as_f64(), > ErrorStatus::UnknownError, >- "Failed to interpret y as float"); >+ "Failed to interpret y as float" >+ ); > > let width = try_opt!( >- try_opt!(resp.result.find("width"), >- ErrorStatus::UnknownError, >- "Failed to find width field").as_f64(), >+ try_opt!( >+ resp.result.find("width"), >+ ErrorStatus::UnknownError, >+ "Failed to find width field" >+ ).as_f64(), > ErrorStatus::UnknownError, >- "Failed to interpret width as float"); >+ "Failed to interpret width as float" >+ ); > > let height = try_opt!( >- try_opt!(resp.result.find("height"), >- ErrorStatus::UnknownError, >- "Failed to find height field").as_f64(), >+ try_opt!( >+ resp.result.find("height"), >+ ErrorStatus::UnknownError, >+ "Failed to find height field" >+ ).as_f64(), > ErrorStatus::UnknownError, >- "Failed to interpret width as float"); >+ "Failed to interpret width as float" >+ ); > >- let rect = ElementRectResponse { x, y, width, height }; >+ let rect = ElementRectResponse { >+ x, >+ y, >+ width, >+ height, >+ }; > WebDriverResponse::ElementRect(rect) >- }, >- FullscreenWindow | MinimizeWindow | MaximizeWindow | GetWindowRect | >- SetWindowRect(_) => { >+ } >+ FullscreenWindow | MinimizeWindow | MaximizeWindow | GetWindowRect >+ | SetWindowRect(_) => { > let width = try_opt!( >- try_opt!(resp.result.find("width"), >- ErrorStatus::UnknownError, >- "Failed to find width field").as_u64(), >+ try_opt!( >+ resp.result.find("width"), >+ ErrorStatus::UnknownError, >+ "Failed to find width field" >+ ).as_u64(), > ErrorStatus::UnknownError, >- "Failed to interpret width as positive integer"); >+ "Failed to interpret width as positive integer" >+ ); > > let height = try_opt!( >- try_opt!(resp.result.find("height"), >- ErrorStatus::UnknownError, >- "Failed to find heigenht field").as_u64(), >+ try_opt!( >+ resp.result.find("height"), >+ ErrorStatus::UnknownError, >+ "Failed to find heigenht field" >+ ).as_u64(), > ErrorStatus::UnknownError, >- "Failed to interpret height as positive integer"); >+ "Failed to interpret height as positive integer" >+ ); > > let x = try_opt!( >- try_opt!(resp.result.find("x"), >- ErrorStatus::UnknownError, >- "Failed to find x field").as_i64(), >+ try_opt!( >+ resp.result.find("x"), >+ ErrorStatus::UnknownError, >+ "Failed to find x field" >+ ).as_i64(), > ErrorStatus::UnknownError, >- "Failed to interpret x as integer"); >+ "Failed to interpret x as integer" >+ ); > > let y = try_opt!( >- try_opt!(resp.result.find("y"), >- ErrorStatus::UnknownError, >- "Failed to find y field").as_i64(), >+ try_opt!( >+ resp.result.find("y"), >+ ErrorStatus::UnknownError, >+ "Failed to find y field" >+ ).as_i64(), > ErrorStatus::UnknownError, >- "Failed to interpret y as integer"); >+ "Failed to interpret y as integer" >+ ); > > let rect = WindowRectResponse { > x: x as i32, > y: y as i32, > width: width as i32, > height: height as i32, > }; > WebDriverResponse::WindowRect(rect) >- }, >+ } > GetCookies => { > let cookies = try!(self.process_cookies(&resp.result)); > WebDriverResponse::Cookies(CookiesResponse { value: cookies }) >- }, >+ } > GetNamedCookie(ref name) => { > let mut cookies = try!(self.process_cookies(&resp.result)); > cookies.retain(|x| x.name == *name); >- let cookie = try_opt!(cookies.pop(), >- ErrorStatus::NoSuchCookie, >- format!("No cookie with name {}", name)); >+ let cookie = try_opt!( >+ cookies.pop(), >+ ErrorStatus::NoSuchCookie, >+ format!("No cookie with name {}", name) >+ ); > WebDriverResponse::Cookie(CookieResponse { value: cookie }) > } > FindElement(_) | FindElementElement(_, _) => { >- let element = try!(self.to_web_element( >- try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, >- "Failed to find value field"))); >+ let element = try!(self.to_web_element(try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ))); > WebDriverResponse::Generic(ValueResponse::new(element.to_json())) >- }, >+ } > FindElements(_) | FindElementElements(_, _) => { >- let element_vec = try_opt!(resp.result.as_array(), >- ErrorStatus::UnknownError, >- "Failed to interpret value as array"); >- let elements = try!(element_vec.iter().map( >- |x| { >- self.to_web_element(x) >- }).collect::<Result<Vec<_>, _>>()); >- WebDriverResponse::Generic(ValueResponse::new( >- Json::Array(elements.iter().map(|x| {x.to_json()}).collect()))) >- }, >+ let element_vec = try_opt!( >+ resp.result.as_array(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret value as array" >+ ); >+ let elements = try!( >+ element_vec >+ .iter() >+ .map(|x| self.to_web_element(x)) >+ .collect::<Result<Vec<_>, _>>() >+ ); >+ WebDriverResponse::Generic(ValueResponse::new(Json::Array( >+ elements.iter().map(|x| x.to_json()).collect(), >+ ))) >+ } > GetActiveElement => { >- let element = try!(self.to_web_element( >- try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, >- "Failed to find value field"))); >+ let element = try!(self.to_web_element(try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ))); > WebDriverResponse::Generic(ValueResponse::new(element.to_json())) >- }, >+ } > NewSession(_) => { > let session_id = try_opt!( >- try_opt!(resp.result.find("sessionId"), >- ErrorStatus::InvalidSessionId, >- "Failed to find sessionId field").as_string(), >+ try_opt!( >+ resp.result.find("sessionId"), >+ ErrorStatus::InvalidSessionId, >+ "Failed to find sessionId field" >+ ).as_string(), > ErrorStatus::InvalidSessionId, >- "sessionId is not a string"); >+ "sessionId is not a string" >+ ); > > let mut capabilities = try_opt!( >- try_opt!(resp.result.find("capabilities"), >- ErrorStatus::UnknownError, >- "Failed to find capabilities field").as_object(), >+ try_opt!( >+ resp.result.find("capabilities"), >+ ErrorStatus::UnknownError, >+ "Failed to find capabilities field" >+ ).as_object(), > ErrorStatus::UnknownError, >- "capabilities field is not an object").clone(); >+ "capabilities field is not an object" >+ ).clone(); > > capabilities.insert("moz:geckodriverVersion".into(), BuildInfo.into()); > > WebDriverResponse::NewSession(NewSessionResponse::new( >- session_id.to_string(), Json::Object(capabilities))) >- }, >- DeleteSession => { >- WebDriverResponse::DeleteSession >- }, >- Extension(ref extension) => { >- match extension { >- &GeckoExtensionCommand::GetContext => { >- let value = try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, >- "Failed to find value field"); >- WebDriverResponse::Generic(ValueResponse::new(value.clone())) >- }, >- &GeckoExtensionCommand::SetContext(_) => WebDriverResponse::Void, >- &GeckoExtensionCommand::XblAnonymousChildren(_) => { >- let els_vec = try_opt!(resp.result.as_array(), >- ErrorStatus::UnknownError, "Failed to interpret body as array"); >- let els = try!(els_vec.iter().map(|x| self.to_web_element(x)) >- .collect::<Result<Vec<_>, _>>()); >- WebDriverResponse::Generic(ValueResponse::new( >- Json::Array(els.iter().map(|el| el.to_json()).collect()))) >- }, >- &GeckoExtensionCommand::XblAnonymousByAttribute(_, _) => { >- let el = try!(self.to_web_element(try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, "Failed to find value field"))); >- WebDriverResponse::Generic(ValueResponse::new(el.to_json())) >- }, >- &GeckoExtensionCommand::InstallAddon(_) => { >- let value = try_opt!(resp.result.find("value"), >- ErrorStatus::UnknownError, >- "Failed to find value field"); >- WebDriverResponse::Generic(ValueResponse::new(value.clone())) >- }, >- &GeckoExtensionCommand::UninstallAddon(_) => WebDriverResponse::Void >- } >+ session_id.to_string(), >+ Json::Object(capabilities), >+ )) > } >+ DeleteSession => WebDriverResponse::DeleteSession, >+ Extension(ref extension) => match extension { >+ &GeckoExtensionCommand::GetContext => { >+ let value = try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ); >+ WebDriverResponse::Generic(ValueResponse::new(value.clone())) >+ } >+ &GeckoExtensionCommand::SetContext(_) => WebDriverResponse::Void, >+ &GeckoExtensionCommand::XblAnonymousChildren(_) => { >+ let els_vec = try_opt!( >+ resp.result.as_array(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret body as array" >+ ); >+ let els = try!( >+ els_vec >+ .iter() >+ .map(|x| self.to_web_element(x)) >+ .collect::<Result<Vec<_>, _>>() >+ ); >+ WebDriverResponse::Generic(ValueResponse::new(Json::Array( >+ els.iter().map(|el| el.to_json()).collect(), >+ ))) >+ } >+ &GeckoExtensionCommand::XblAnonymousByAttribute(_, _) => { >+ let el = try!(self.to_web_element(try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ))); >+ WebDriverResponse::Generic(ValueResponse::new(el.to_json())) >+ } >+ &GeckoExtensionCommand::InstallAddon(_) => { >+ let value = try_opt!( >+ resp.result.find("value"), >+ ErrorStatus::UnknownError, >+ "Failed to find value field" >+ ); >+ WebDriverResponse::Generic(ValueResponse::new(value.clone())) >+ } >+ &GeckoExtensionCommand::UninstallAddon(_) => WebDriverResponse::Void, >+ }, > }) > } > > fn process_cookies(&self, json_data: &Json) -> WebDriverResult<Vec<Cookie>> { >- let value = try_opt!(json_data.as_array(), >- ErrorStatus::UnknownError, >- "Failed to interpret value as array"); >- value.iter().map(|x| { >- let name = try_opt!( >- try_opt!(x.find("name"), >- ErrorStatus::UnknownError, >- "Cookie must have a name field").as_string(), >- ErrorStatus::UnknownError, >- "Cookie must have string name").to_string(); >- let value = try_opt!( >- try_opt!(x.find("value"), >- ErrorStatus::UnknownError, >- "Cookie must have a value field").as_string(), >- ErrorStatus::UnknownError, >- "Cookie must have a string value").to_string(); >- let path = try!( >- Nullable::from_json(x.find("path").unwrap_or(&Json::Null), >- |x| { >- Ok((try_opt!(x.as_string(), >- ErrorStatus::UnknownError, >- "Cookie path must be string")).to_string()) >- })); >- let domain = try!( >- Nullable::from_json(x.find("domain").unwrap_or(&Json::Null), >- |x| { >- Ok((try_opt!(x.as_string(), >- ErrorStatus::UnknownError, >- "Cookie domain must be string")).to_string()) >- })); >- let expiry = try!( >- Nullable::from_json(x.find("expiry").unwrap_or(&Json::Null), >- |x| { >- Ok(Date::new(try_opt!( >- x.as_u64(), >- ErrorStatus::UnknownError, >- "Cookie expiry must be a positive integer"))) >- })); >- let secure = try_opt!( >- x.find("secure").map_or(Some(false), |x| x.as_boolean()), >- ErrorStatus::UnknownError, >- "Cookie secure flag must be boolean"); >- let http_only = try_opt!( >- x.find("httpOnly").map_or(Some(false), |x| x.as_boolean()), >- ErrorStatus::UnknownError, >- "Cookie httpOnly flag must be boolean"); >+ let value = try_opt!( >+ json_data.as_array(), >+ ErrorStatus::UnknownError, >+ "Failed to interpret value as array" >+ ); >+ value >+ .iter() >+ .map(|x| { >+ let name = try_opt!( >+ try_opt!( >+ x.find("name"), >+ ErrorStatus::UnknownError, >+ "Cookie must have a name field" >+ ).as_string(), >+ ErrorStatus::UnknownError, >+ "Cookie must have string name" >+ ).to_string(); >+ let value = try_opt!( >+ try_opt!( >+ x.find("value"), >+ ErrorStatus::UnknownError, >+ "Cookie must have a value field" >+ ).as_string(), >+ ErrorStatus::UnknownError, >+ "Cookie must have a string value" >+ ).to_string(); >+ let path = try!(Nullable::from_json( >+ x.find("path").unwrap_or(&Json::Null), >+ |x| Ok((try_opt!( >+ x.as_string(), >+ ErrorStatus::UnknownError, >+ "Cookie path must be string" >+ )).to_string()) >+ )); >+ let domain = try!(Nullable::from_json( >+ x.find("domain").unwrap_or(&Json::Null), >+ |x| Ok((try_opt!( >+ x.as_string(), >+ ErrorStatus::UnknownError, >+ "Cookie domain must be string" >+ )).to_string()) >+ )); >+ let expiry = try!(Nullable::from_json( >+ x.find("expiry").unwrap_or(&Json::Null), >+ |x| Ok(Date::new(try_opt!( >+ x.as_u64(), >+ ErrorStatus::UnknownError, >+ "Cookie expiry must be a positive integer" >+ ))) >+ )); >+ let secure = try_opt!( >+ x.find("secure").map_or(Some(false), |x| x.as_boolean()), >+ ErrorStatus::UnknownError, >+ "Cookie secure flag must be boolean" >+ ); >+ let http_only = try_opt!( >+ x.find("httpOnly").map_or(Some(false), |x| x.as_boolean()), >+ ErrorStatus::UnknownError, >+ "Cookie httpOnly flag must be boolean" >+ ); > >- let new_cookie = Cookie { >- name: name, >- value: value, >- path: path, >- domain: domain, >- expiry: expiry, >- secure: secure, >- httpOnly: http_only, >- }; >- Ok(new_cookie) >- }).collect::<Result<Vec<_>, _>>() >+ let new_cookie = Cookie { >+ name: name, >+ value: value, >+ path: path, >+ domain: domain, >+ expiry: expiry, >+ secure: secure, >+ httpOnly: http_only, >+ }; >+ Ok(new_cookie) >+ }).collect::<Result<Vec<_>, _>>() > } > } > > pub struct MarionetteCommand { > pub id: u64, > pub name: String, >- pub params: BTreeMap<String, Json> >+ pub params: BTreeMap<String, Json>, > } > > impl MarionetteCommand { > fn new(id: u64, name: String, params: BTreeMap<String, Json>) -> MarionetteCommand { > MarionetteCommand { > id: id, > name: name, > params: params, > } > } > >- fn from_webdriver_message(id: u64, >- capabilities: Option<BTreeMap<String, Json>>, >- msg: &WebDriverMessage<GeckoExtensionRoute>) >- -> WebDriverResult<MarionetteCommand> { >+ fn from_webdriver_message( >+ id: u64, >+ capabilities: Option<BTreeMap<String, Json>>, >+ msg: &WebDriverMessage<GeckoExtensionRoute>, >+ ) -> WebDriverResult<MarionetteCommand> { > let (opt_name, opt_parameters) = match msg.command { > Status => panic!("Got status command that should already have been handled"), > AcceptAlert => { > // Needs to be updated to "WebDriver:AcceptAlert" for Firefox 63 > (Some("WebDriver:AcceptDialog"), None) > } > AddCookie(ref x) => (Some("WebDriver:AddCookie"), Some(x.to_marionette())), > CloseWindow => (Some("WebDriver:CloseWindow"), None), >@@ -1196,120 +1392,159 @@ impl MarionetteCommand { > data.insert("using".to_owned(), "anon".to_json()); > data.insert("value".to_owned(), Json::Null); > data.insert("element".to_string(), e.id.to_json()); > (Some("WebDriver:FindElements"), Some(Ok(data))) > } > }, > }; > >- let name = try_opt!(opt_name, >- ErrorStatus::UnsupportedOperation, >- "Operation not supported"); >+ let name = try_opt!( >+ opt_name, >+ ErrorStatus::UnsupportedOperation, >+ "Operation not supported" >+ ); > let parameters = try!(opt_parameters.unwrap_or(Ok(BTreeMap::new()))); > > Ok(MarionetteCommand::new(id, name.into(), parameters)) > } > } > > impl ToJson for MarionetteCommand { > fn to_json(&self) -> Json { >- Json::Array(vec![Json::U64(0), self.id.to_json(), self.name.to_json(), >- self.params.to_json()]) >+ Json::Array(vec![ >+ Json::U64(0), >+ self.id.to_json(), >+ self.name.to_json(), >+ self.params.to_json(), >+ ]) > } > } > > pub struct MarionetteResponse { > pub id: u64, > pub error: Option<MarionetteError>, > pub result: Json, > } > > impl MarionetteResponse { > fn from_json(data: &Json) -> WebDriverResult<MarionetteResponse> { >- let data_array = try_opt!(data.as_array(), >- ErrorStatus::UnknownError, >- "Expected a json array"); >+ let data_array = try_opt!( >+ data.as_array(), >+ ErrorStatus::UnknownError, >+ "Expected a json array" >+ ); > > if data_array.len() != 4 { > return Err(WebDriverError::new( > ErrorStatus::UnknownError, >- "Expected an array of length 4")); >+ "Expected an array of length 4", >+ )); > } > > if data_array[0].as_u64() != Some(1) { >- return Err(WebDriverError::new(ErrorStatus::UnknownError, >- "Expected 1 in first element of response")); >+ return Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Expected 1 in first element of response", >+ )); > }; >- let id = try_opt!(data[1].as_u64(), >- ErrorStatus::UnknownError, >- "Expected an integer id"); >+ let id = try_opt!( >+ data[1].as_u64(), >+ ErrorStatus::UnknownError, >+ "Expected an integer id" >+ ); > let error = if data[2].is_object() { > Some(try!(MarionetteError::from_json(&data[2]))) > } else if data[2].is_null() { > None > } else { >- return Err(WebDriverError::new(ErrorStatus::UnknownError, >- "Expected object or null error")); >+ return Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Expected object or null error", >+ )); > }; > > let result = if data[3].is_null() || data[3].is_object() || data[3].is_array() { > data[3].clone() > } else { >- return Err(WebDriverError::new(ErrorStatus::UnknownError, >- "Expected object params")); >+ return Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Expected object params", >+ )); > }; > >- Ok(MarionetteResponse {id: id, >- error: error, >- result: result}) >+ Ok(MarionetteResponse { >+ id: id, >+ error: error, >+ result: result, >+ }) > } > } > > impl ToJson for MarionetteResponse { > fn to_json(&self) -> Json { >- Json::Array(vec![Json::U64(1), self.id.to_json(), self.error.to_json(), >- self.result.clone()]) >+ Json::Array(vec![ >+ Json::U64(1), >+ self.id.to_json(), >+ self.error.to_json(), >+ self.result.clone(), >+ ]) > } > } > > #[derive(RustcEncodable, RustcDecodable)] > pub struct MarionetteError { > pub code: String, > pub message: String, >- pub stacktrace: Option<String> >+ pub stacktrace: Option<String>, > } > > impl MarionetteError { > fn from_json(data: &Json) -> WebDriverResult<MarionetteError> { > if !data.is_object() { >- return Err(WebDriverError::new(ErrorStatus::UnknownError, >- "Expected an error object")); >+ return Err(WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Expected an error object", >+ )); > } > > let code = try_opt!( >- try_opt!(data.find("error"), >- ErrorStatus::UnknownError, >- "Error value has no error code").as_string(), >+ try_opt!( >+ data.find("error"), >+ ErrorStatus::UnknownError, >+ "Error value has no error code" >+ ).as_string(), > ErrorStatus::UnknownError, >- "Error status was not a string").into(); >+ "Error status was not a string" >+ ).into(); > let message = try_opt!( >- try_opt!(data.find("message"), >- ErrorStatus::UnknownError, >- "Error value has no message").as_string(), >+ try_opt!( >+ data.find("message"), >+ ErrorStatus::UnknownError, >+ "Error value has no message" >+ ).as_string(), > ErrorStatus::UnknownError, >- "Error message was not a string").into(); >+ "Error message was not a string" >+ ).into(); > let stacktrace = match data.find("stacktrace") { > None | Some(&Json::Null) => None, >- Some(x) => Some(try_opt!(x.as_string(), >- ErrorStatus::UnknownError, >- "Error message was not a string").into()), >+ Some(x) => Some( >+ try_opt!( >+ x.as_string(), >+ ErrorStatus::UnknownError, >+ "Error message was not a string" >+ ).into(), >+ ), > }; > >- Ok(MarionetteError { code, message, stacktrace }) >+ Ok(MarionetteError { >+ code, >+ message, >+ stacktrace, >+ }) > } > } > > impl ToJson for MarionetteError { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("error".into(), self.code.to_json()); > data.insert("message".into(), self.message.to_json()); >@@ -1335,17 +1570,17 @@ fn get_free_port() -> IoResult<u16> { > TcpListener::bind((DEFAULT_HOST, 0)) > .and_then(|stream| stream.local_addr()) > .map(|x| x.port()) > } > > pub struct MarionetteConnection { > port: u16, > stream: Option<TcpStream>, >- pub session: MarionetteSession >+ pub session: MarionetteSession, > } > > impl MarionetteConnection { > pub fn new(port: u16, session_id: Option<String>) -> MarionetteConnection { > MarionetteConnection { > port: port, > stream: None, > session: MarionetteSession::new(session_id), >@@ -1405,83 +1640,110 @@ impl MarionetteConnection { > debug!("Connected to Marionette on {}:{}", DEFAULT_HOST, self.port); > self.handshake() > } > > fn handshake(&mut self) -> WebDriverResult<()> { > let resp = try!(self.read_resp()); > let handshake_data = try!(Json::from_str(&*resp)); > >- let data = try_opt!(handshake_data.as_object(), >- ErrorStatus::UnknownError, >- "Expected a json object in handshake"); >+ let data = try_opt!( >+ handshake_data.as_object(), >+ ErrorStatus::UnknownError, >+ "Expected a json object in handshake" >+ ); > >- self.session.protocol = Some(try_opt!(data.get("marionetteProtocol"), >- ErrorStatus::UnknownError, >- "Missing 'marionetteProtocol' field in handshake").to_string()); >+ self.session.protocol = Some( >+ try_opt!( >+ data.get("marionetteProtocol"), >+ ErrorStatus::UnknownError, >+ "Missing 'marionetteProtocol' field in handshake" >+ ).to_string(), >+ ); > >- self.session.application_type = Some(try_opt!(data.get("applicationType"), >- ErrorStatus::UnknownError, >- "Missing 'applicationType' field in handshake").to_string()); >+ self.session.application_type = Some( >+ try_opt!( >+ data.get("applicationType"), >+ ErrorStatus::UnknownError, >+ "Missing 'applicationType' field in handshake" >+ ).to_string(), >+ ); > > if self.session.protocol != Some("3".into()) { > return Err(WebDriverError::new( > ErrorStatus::UnknownError, >- format!("Unsupported Marionette protocol version {}, required 3", >- self.session.protocol.as_ref().unwrap_or(&"<unknown>".into())))); >+ format!( >+ "Unsupported Marionette protocol version {}, required 3", >+ self.session >+ .protocol >+ .as_ref() >+ .unwrap_or(&"<unknown>".into()) >+ ), >+ )); > } > > Ok(()) > } > >- pub fn close(&self) { >- } >+ pub fn close(&self) {} > >- fn encode_msg(&self, msg:Json) -> String { >+ fn encode_msg(&self, msg: Json) -> String { > let data = json::encode(&msg).unwrap(); > format!("{}:{}", data.len(), data) > } > >- pub fn send_command(&mut self, >- capabilities: Option<BTreeMap<String, Json>>, >- msg: &WebDriverMessage<GeckoExtensionRoute>) >- -> WebDriverResult<WebDriverResponse> { >+ pub fn send_command( >+ &mut self, >+ capabilities: Option<BTreeMap<String, Json>>, >+ msg: &WebDriverMessage<GeckoExtensionRoute>, >+ ) -> WebDriverResult<WebDriverResponse> { > let id = self.session.next_command_id(); >- let command = try!(MarionetteCommand::from_webdriver_message(id, capabilities, msg)); >+ let command = try!(MarionetteCommand::from_webdriver_message( >+ id, >+ capabilities, >+ msg >+ )); > > let resp_data = try!(self.send(command.to_json())); > let json_data: Json = try!(Json::from_str(&*resp_data)); > >- self.session.response(msg, try!(MarionetteResponse::from_json(&json_data))) >+ self.session >+ .response(msg, try!(MarionetteResponse::from_json(&json_data))) > } > > fn send(&mut self, msg: Json) -> WebDriverResult<String> { > let data = self.encode_msg(msg); > > match self.stream { > Some(ref mut stream) => { > if stream.write(&*data.as_bytes()).is_err() { >- let mut err = WebDriverError::new(ErrorStatus::UnknownError, >- "Failed to write response to stream"); >+ let mut err = WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Failed to write response to stream", >+ ); > err.delete_session = true; > return Err(err); > } > } > None => { >- let mut err = WebDriverError::new(ErrorStatus::UnknownError, >- "Tried to write before opening stream"); >+ let mut err = WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Tried to write before opening stream", >+ ); > err.delete_session = true; > return Err(err); > } > } > match self.read_resp() { > Ok(resp) => Ok(resp), > Err(_) => { >- let mut err = WebDriverError::new(ErrorStatus::UnknownError, >- "Failed to decode response from marionette"); >+ let mut err = WebDriverError::new( >+ ErrorStatus::UnknownError, >+ "Failed to decode response from marionette", >+ ); > err.delete_session = true; > Err(err) > } > } > } > > fn read_resp(&mut self) -> IoResult<String> { > let mut bytes = 0usize; >@@ -1512,18 +1774,20 @@ impl MarionetteConnection { > } > > let buf = &mut [0 as u8; 8192]; > let mut payload = Vec::with_capacity(bytes); > let mut total_read = 0; > while total_read < bytes { > let num_read = try!(stream.read(buf)); > if num_read == 0 { >- return Err(IoError::new(ErrorKind::Other, >- "EOF reading marionette message")) >+ return Err(IoError::new( >+ ErrorKind::Other, >+ "EOF reading marionette message", >+ )); > } > total_read += num_read; > for x in &buf[..num_read] { > payload.push(*x); > } > } > > // TODO(jgraham): Need to handle the error here >@@ -1532,46 +1796,59 @@ impl MarionetteConnection { > } > > trait ToMarionette { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>>; > } > > impl ToMarionette for GetParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), ErrorStatus::UnknownError, "Expected an object").clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for TimeoutsParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), ErrorStatus::UnknownError, "Expected an object").clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for WindowRectParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), ErrorStatus::UnknownError, "Expected an object").clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for SwitchToWindowParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut data = BTreeMap::new(); > data.insert("name".to_string(), self.handle.to_json()); > Ok(data) > } > } > > impl ToMarionette for LocatorParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), >- ErrorStatus::UnknownError, >- "Expected an object") >- .clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for SwitchToFrameParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut data = BTreeMap::new(); > let key = match self.id { > FrameId::Null => None, >@@ -1592,29 +1869,31 @@ impl ToMarionette for JavascriptCommandParameters { > data.insert("specialPowers".to_string(), false.to_json()); > data.insert("scriptTimeout".to_string(), Json::Null); > Ok(data) > } > } > > impl ToMarionette for ActionsParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), >- ErrorStatus::UnknownError, >- "Expected an object") >- .clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for GetNamedCookieParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >- Ok(try_opt!(self.to_json().as_object(), >- ErrorStatus::UnknownError, >- "Expected an object") >- .clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for AddCookieParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut cookie = BTreeMap::new(); > cookie.insert("name".to_string(), self.name.to_json()); > cookie.insert("value".to_string(), self.value.to_json()); >@@ -1635,17 +1914,17 @@ impl ToMarionette for AddCookieParameters { > } > } > > impl ToMarionette for TakeScreenshotParameters { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut data = BTreeMap::new(); > let element = match self.element { > Nullable::Null => Json::Null, >- Nullable::Value(ref x) => Json::Object(try!(x.to_marionette())) >+ Nullable::Value(ref x) => Json::Object(try!(x.to_marionette())), > }; > data.insert("element".to_string(), element); > Ok(data) > } > } > > impl ToMarionette for WebElement { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { >@@ -1655,69 +1934,75 @@ impl ToMarionette for WebElement { > } > } > > impl<T: ToJson> ToMarionette for Nullable<T> { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > //Note this is a terrible hack. We don't want Nullable<T: ToJson+ToMarionette> > //so in cases where ToJson != ToMarionette you have to deal with the Nullable > //explicitly. This kind of suggests that the whole design is wrong. >- Ok(try_opt!(self.to_json().as_object(), ErrorStatus::UnknownError, "Expected an object").clone()) >+ Ok(try_opt!( >+ self.to_json().as_object(), >+ ErrorStatus::UnknownError, >+ "Expected an object" >+ ).clone()) > } > } > > impl ToMarionette for FrameId { > fn to_marionette(&self) -> WebDriverResult<BTreeMap<String, Json>> { > let mut data = BTreeMap::new(); > match *self { > FrameId::Short(x) => data.insert("id".to_string(), x.to_json()), >- FrameId::Element(ref x) => data.insert("element".to_string(), >- Json::Object(try!(x.to_marionette()))), >- FrameId::Null => None >+ FrameId::Element(ref x) => { >+ data.insert("element".to_string(), Json::Object(try!(x.to_marionette()))) >+ } >+ FrameId::Null => None, > }; > Ok(data) > } > } > > #[cfg(test)] > mod tests { > use marionette::{AddonInstallParameters, Parameters}; > use rustc_serialize::json::Json; >- use std::io::Read; > use std::fs::File; >+ use std::io::Read; > use webdriver::error::WebDriverResult; > > #[test] > fn test_addon_install_params_missing_path() { > let json_data: Json = Json::from_str(r#"{"temporary": true}"#).unwrap(); > let res: WebDriverResult<AddonInstallParameters> = Parameters::from_json(&json_data); > assert!(res.is_err()); > } > > #[test] > fn test_addon_install_params_with_both_path_and_base64() { >- let json_data: Json = Json::from_str( >- r#"{"path": "/path/to.xpi", "addon": "aGVsbG8=", "temporary": true}"#).unwrap(); >+ let json_data: Json = >+ Json::from_str(r#"{"path": "/path/to.xpi", "addon": "aGVsbG8=", "temporary": true}"#) >+ .unwrap(); > let res: WebDriverResult<AddonInstallParameters> = Parameters::from_json(&json_data); > assert!(res.is_err()); > } > > #[test] > fn test_addon_install_params_with_path() { >- let json_data: Json = Json::from_str( >- r#"{"path": "/path/to.xpi", "temporary": true}"#).unwrap(); >+ let json_data: Json = >+ Json::from_str(r#"{"path": "/path/to.xpi", "temporary": true}"#).unwrap(); > let parameters: AddonInstallParameters = Parameters::from_json(&json_data).unwrap(); > assert_eq!(parameters.path, "/path/to.xpi"); > assert_eq!(parameters.temporary, true); > } > > #[test] > fn test_addon_install_params_with_base64() { >- let json_data: Json = Json::from_str( >- r#"{"addon": "aGVsbG8=", "temporary": true}"#).unwrap(); >+ let json_data: Json = >+ Json::from_str(r#"{"addon": "aGVsbG8=", "temporary": true}"#).unwrap(); > let parameters: AddonInstallParameters = Parameters::from_json(&json_data).unwrap(); > > assert_eq!(parameters.temporary, true); > let mut file = File::open(parameters.path).unwrap(); > let mut contents = String::new(); > file.read_to_string(&mut contents).unwrap(); > assert_eq!("hello", contents); > } >diff --git a/testing/mozbase/rust/mozprofile/src/lib.rs b/testing/mozbase/rust/mozprofile/src/lib.rs >index ef7a52274b0f..86816201717f 100644 >--- a/testing/mozbase/rust/mozprofile/src/lib.rs >+++ b/testing/mozbase/rust/mozprofile/src/lib.rs >@@ -1,146 +1,133 @@ > extern crate tempdir; > >-pub mod profile; > pub mod preferences; > pub mod prefreader; >- >+pub mod profile; > > #[cfg(test)] > mod test { >-// use std::fs::File; >-// use profile::Profile; >- use prefreader::{parse, tokenize, serialize}; >- use prefreader::{PrefToken, Position}; >+ // use std::fs::File; >+ // use profile::Profile; > use preferences::Pref; >+ use prefreader::{parse, serialize, tokenize}; >+ use prefreader::{Position, PrefToken}; > use std::collections::BTreeMap; > use std::error::Error; > use std::io::Cursor; > use std::str; > > #[test] > fn tokenize_simple() { > let prefs = " user_pref ( 'example.pref.string', 'value' ) ;\n pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false);"; > > let p = Position::new(); > >- let expected = vec![PrefToken::UserPrefFunction(p), >- PrefToken::Paren('(', p), >- PrefToken::String("example.pref.string".into(), p), >- PrefToken::Comma(p), >- PrefToken::String("value".into(), p), >- PrefToken::Paren(')', p), >- PrefToken::Semicolon(p), >- PrefToken::PrefFunction(p), >- PrefToken::Paren('(', p), >- PrefToken::String("example.pref.int".into(), p), >- PrefToken::Comma(p), >- PrefToken::Int(-123, p), >- PrefToken::Paren(')', p), >- PrefToken::Semicolon(p), >- PrefToken::StickyPrefFunction(p), >- PrefToken::Paren('(', p), >- PrefToken::String("example.pref.bool".into(), p), >- PrefToken::Comma(p), >- PrefToken::Bool(false, p), >- PrefToken::Paren(')', p), >- PrefToken::Semicolon(p)]; >+ let expected = vec![ >+ PrefToken::UserPrefFunction(p), >+ PrefToken::Paren('(', p), >+ PrefToken::String("example.pref.string".into(), p), >+ PrefToken::Comma(p), >+ PrefToken::String("value".into(), p), >+ PrefToken::Paren(')', p), >+ PrefToken::Semicolon(p), >+ PrefToken::PrefFunction(p), >+ PrefToken::Paren('(', p), >+ PrefToken::String("example.pref.int".into(), p), >+ PrefToken::Comma(p), >+ PrefToken::Int(-123, p), >+ PrefToken::Paren(')', p), >+ PrefToken::Semicolon(p), >+ PrefToken::StickyPrefFunction(p), >+ PrefToken::Paren('(', p), >+ PrefToken::String("example.pref.bool".into(), p), >+ PrefToken::Comma(p), >+ PrefToken::Bool(false, p), >+ PrefToken::Paren(')', p), >+ PrefToken::Semicolon(p), >+ ]; > > tokenize_test(prefs, &expected); > } > > #[test] > fn tokenize_comments() { > let prefs = "# bash style comment\n /*block comment*/ user_pref/*block comment*/(/*block comment*/ 'example.pref.string' /*block comment*/,/*block comment*/ 'value'/*block comment*/ )// line comment"; > > let p = Position::new(); > >- let expected = vec![PrefToken::CommentBashLine(" bash style comment".into(), p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::UserPrefFunction(p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::Paren('(', p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::String("example.pref.string".into(), p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::Comma(p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::String("value".into(), p), >- PrefToken::CommentBlock("block comment".into(), p), >- PrefToken::Paren(')', p), >- PrefToken::CommentLine(" line comment".into(), p)]; >+ let expected = vec![ >+ PrefToken::CommentBashLine(" bash style comment".into(), p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::UserPrefFunction(p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::Paren('(', p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::String("example.pref.string".into(), p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::Comma(p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::String("value".into(), p), >+ PrefToken::CommentBlock("block comment".into(), p), >+ PrefToken::Paren(')', p), >+ PrefToken::CommentLine(" line comment".into(), p), >+ ]; > > tokenize_test(prefs, &expected); > } > > #[test] > fn tokenize_escapes() { > let prefs = r#"user_pref('example\x20pref', "\u0020\u2603\uD800\uDC96\"\'\n\r\\\w)"#; > > let p = Position::new(); > >- let expected = vec![PrefToken::UserPrefFunction(p), >- PrefToken::Paren('(', p), >- PrefToken::String("example pref".into(), p), >- PrefToken::Comma(p), >- PrefToken::String(" âð\"'\n\r\\\\w".into(), p), >- PrefToken::Paren(')', p)]; >+ let expected = vec![ >+ PrefToken::UserPrefFunction(p), >+ PrefToken::Paren('(', p), >+ PrefToken::String("example pref".into(), p), >+ PrefToken::Comma(p), >+ PrefToken::String(" âð\"'\n\r\\\\w".into(), p), >+ PrefToken::Paren(')', p), >+ ]; > > tokenize_test(prefs, &expected); > } > > fn tokenize_test(prefs: &str, expected: &[PrefToken]) { > println!("{}\n", prefs); > > for (e, a) in expected.iter().zip(tokenize(prefs.as_bytes())) { > let success = match (e, &a) { >- (&PrefToken::PrefFunction(_), >- &PrefToken::PrefFunction(_)) => true, >- (&PrefToken::UserPrefFunction(_), >- &PrefToken::UserPrefFunction(_)) => true, >- (&PrefToken::StickyPrefFunction(_), >- &PrefToken::StickyPrefFunction(_)) => true, >- (&PrefToken::CommentBlock(ref data_e, _), >- &PrefToken::CommentBlock(ref data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::CommentLine(ref data_e, _), >- &PrefToken::CommentLine(ref data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::CommentBashLine(ref data_e, _), >- &PrefToken::CommentBashLine(ref data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::Paren(data_e, _), >- &PrefToken::Paren(data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::Semicolon(_), >- &PrefToken::Semicolon(_)) => true, >- (&PrefToken::Comma(_), >- &PrefToken::Comma(_)) => true, >- (&PrefToken::String(ref data_e, _), >- &PrefToken::String(ref data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::Int(data_e, _), >- &PrefToken::Int(data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::Bool(data_e, _), >- &PrefToken::Bool(data_a, _)) => { >- data_e == data_a >- }, >- (&PrefToken::Error(data_e, _), >- &PrefToken::Error(data_a, _)) => { >- data_e == data_a >- }, >- (_, _) => false >+ (&PrefToken::PrefFunction(_), &PrefToken::PrefFunction(_)) => true, >+ (&PrefToken::UserPrefFunction(_), &PrefToken::UserPrefFunction(_)) => true, >+ (&PrefToken::StickyPrefFunction(_), &PrefToken::StickyPrefFunction(_)) => true, >+ ( >+ &PrefToken::CommentBlock(ref data_e, _), >+ &PrefToken::CommentBlock(ref data_a, _), >+ ) => data_e == data_a, >+ ( >+ &PrefToken::CommentLine(ref data_e, _), >+ &PrefToken::CommentLine(ref data_a, _), >+ ) => data_e == data_a, >+ ( >+ &PrefToken::CommentBashLine(ref data_e, _), >+ &PrefToken::CommentBashLine(ref data_a, _), >+ ) => data_e == data_a, >+ (&PrefToken::Paren(data_e, _), &PrefToken::Paren(data_a, _)) => data_e == data_a, >+ (&PrefToken::Semicolon(_), &PrefToken::Semicolon(_)) => true, >+ (&PrefToken::Comma(_), &PrefToken::Comma(_)) => true, >+ (&PrefToken::String(ref data_e, _), &PrefToken::String(ref data_a, _)) => { >+ data_e == data_a >+ } >+ (&PrefToken::Int(data_e, _), &PrefToken::Int(data_a, _)) => data_e == data_a, >+ (&PrefToken::Bool(data_e, _), &PrefToken::Bool(data_a, _)) => data_e == data_a, >+ (&PrefToken::Error(data_e, _), &PrefToken::Error(data_a, _)) => data_e == data_a, >+ (_, _) => false, > }; > if !success { > println!("Expected {:?}, got {:?}", e, a); > } > assert!(success); > } > } > >@@ -172,17 +159,17 @@ mod test { > println!("Expected:\n{:?}\nActual\n{:?}", expected, actual); > assert_eq!(actual, &expected); > } > Err(e) => { > println!("{}", e.description()); > assert!(false) > } > } >- } >+ } > > #[test] > fn serialize_simple() { > let input = " user_pref /* block comment */ ( 'example.pref.string', 'value' ) ;\n pref(\"example.pref.int\", -123); sticky_pref('example.pref.bool',false)"; > let expected = "sticky_pref(\"example.pref.bool\", false); > user_pref(\"example.pref.int\", -123); > user_pref(\"example.pref.string\", \"value\");\n"; > >diff --git a/testing/mozbase/rust/mozprofile/src/preferences.rs b/testing/mozbase/rust/mozprofile/src/preferences.rs >index 619b708fee11..ee9c24510ba5 100644 >--- a/testing/mozbase/rust/mozprofile/src/preferences.rs >+++ b/testing/mozbase/rust/mozprofile/src/preferences.rs >@@ -107,17 +107,20 @@ mod test { > #[test] > fn test_bool() { > assert_eq!(PrefValue::from(true), PrefValue::Bool(true)); > } > > #[test] > fn test_string() { > assert_eq!(PrefValue::from("foo"), PrefValue::String("foo".to_string())); >- assert_eq!(PrefValue::from("foo".to_string()), PrefValue::String("foo".to_string())); >+ assert_eq!( >+ PrefValue::from("foo".to_string()), >+ PrefValue::String("foo".to_string()) >+ ); > } > > #[test] > fn test_int() { > assert_eq!(PrefValue::from(42i8), PrefValue::Int(42i64)); > assert_eq!(PrefValue::from(42u8), PrefValue::Int(42i64)); > assert_eq!(PrefValue::from(42i16), PrefValue::Int(42i64)); > assert_eq!(PrefValue::from(42u16), PrefValue::Int(42i64)); >diff --git a/testing/mozbase/rust/mozprofile/src/prefreader.rs b/testing/mozbase/rust/mozprofile/src/prefreader.rs >index ba2507cdbc50..30c5cf188929 100644 >--- a/testing/mozbase/rust/mozprofile/src/prefreader.rs >+++ b/testing/mozbase/rust/mozprofile/src/prefreader.rs >@@ -1,57 +1,60 @@ > use preferences::{Pref, PrefValue, Preferences}; > use std::borrow::Borrow; > use std::borrow::Cow; > use std::char; > use std::error::Error; > use std::fmt; > use std::io::{self, Write}; > use std::iter::Iterator; >-use std::str; > use std::mem; > use std::ops::Deref; >+use std::str; > > impl PrefReaderError { >- fn new(message: &'static str, position: Position, parent: Option<Box<Error>>) -> PrefReaderError { >+ fn new( >+ message: &'static str, >+ position: Position, >+ parent: Option<Box<Error>>, >+ ) -> PrefReaderError { > PrefReaderError { > message: message, > position: position, >- parent: parent >+ parent: parent, > } > } > } > >- > impl fmt::Display for PrefReaderError { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { >- write!(f, "{} at line {}, column {}", >- self.message, self.position.line, self.position.column) >+ write!( >+ f, >+ "{} at line {}, column {}", >+ self.message, self.position.line, self.position.column >+ ) > } > } > >- > impl Error for PrefReaderError { > fn description(&self) -> &str { > self.message > } > > fn cause(&self) -> Option<&Error> { > match self.parent { > None => None, >- Some(ref cause) => Some(cause.deref()) >+ Some(ref cause) => Some(cause.deref()), > } > } > } > > impl From<io::Error> for PrefReaderError { > fn from(err: io::Error) -> PrefReaderError { >- PrefReaderError::new("IOError", >- Position::new(), >- Some(err.into())) >+ PrefReaderError::new("IOError", Position::new(), Some(err.into())) > } > } > > #[derive(Copy, Clone, Debug, PartialEq)] > enum TokenizerState { > Junk, > CommentStart, > CommentLine, >@@ -67,25 +70,22 @@ enum TokenizerState { > AfterFunctionArg, > AfterFunction, > Error, > } > > #[derive(Copy, Clone, Debug, PartialEq)] > pub struct Position { > line: u32, >- column: u32 >+ column: u32, > } > > impl Position { > pub fn new() -> Position { >- Position { >- line: 1, >- column: 0 >- } >+ Position { line: 1, column: 0 } > } > } > > #[derive(Copy, Clone, Debug, PartialEq)] > pub enum TokenType { > None, > PrefFunction, > UserPrefFunction, >@@ -94,34 +94,34 @@ pub enum TokenType { > CommentLine, > CommentBashLine, > Paren, > Semicolon, > Comma, > String, > Int, > Bool, >- Error >+ Error, > } > > #[derive(Debug, PartialEq)] > pub enum PrefToken<'a> { > PrefFunction(Position), > UserPrefFunction(Position), > StickyPrefFunction(Position), > CommentBlock(Cow<'a, str>, Position), > CommentLine(Cow<'a, str>, Position), > CommentBashLine(Cow<'a, str>, Position), > Paren(char, Position), > Semicolon(Position), > Comma(Position), > String(Cow<'a, str>, Position), > Int(i64, Position), > Bool(bool, Position), >- Error(&'static str, Position) >+ Error(&'static str, Position), > } > > impl<'a> PrefToken<'a> { > fn position(&self) -> Position { > match *self { > PrefToken::PrefFunction(position) => position, > PrefToken::UserPrefFunction(position) => position, > PrefToken::StickyPrefFunction(position) => position, >@@ -129,26 +129,26 @@ impl<'a> PrefToken<'a> { > PrefToken::CommentLine(_, position) => position, > PrefToken::CommentBashLine(_, position) => position, > PrefToken::Paren(_, position) => position, > PrefToken::Semicolon(position) => position, > PrefToken::Comma(position) => position, > PrefToken::String(_, position) => position, > PrefToken::Int(_, position) => position, > PrefToken::Bool(_, position) => position, >- PrefToken::Error(_, position) => position >+ PrefToken::Error(_, position) => position, > } > } > } > > #[derive(Debug)] > pub struct PrefReaderError { > message: &'static str, > position: Position, >- parent: Option<Box<Error>> >+ parent: Option<Box<Error>>, > } > > struct TokenData<'a> { > token_type: TokenType, > complete: bool, > position: Position, > data: Cow<'a, str>, > start_pos: usize, >@@ -175,18 +175,21 @@ impl<'a> TokenData<'a> { > self.complete = true; > self.add_slice_to_token(buf, end_pos) > } > > fn add_slice_to_token(&mut self, buf: &'a [u8], end_pos: usize) -> Result<(), PrefReaderError> { > let data = match str::from_utf8(&buf[self.start_pos..end_pos]) { > Ok(x) => x, > Err(_) => { >- return Err(PrefReaderError::new("Could not convert string to utf8", >- self.position, None)); >+ return Err(PrefReaderError::new( >+ "Could not convert string to utf8", >+ self.position, >+ None, >+ )); > } > }; > if self.data != "" { > self.data.to_mut().push_str(&data) > } else { > self.data = Cow::Borrowed(&data) > }; > Ok(()) >@@ -230,41 +233,41 @@ impl<'a> PrefTokenizer<'a> { > TokenType::CommentBlock => PrefToken::CommentBlock(buf, position), > TokenType::CommentLine => PrefToken::CommentLine(buf, position), > TokenType::CommentBashLine => PrefToken::CommentBashLine(buf, position), > TokenType::Paren => { > if buf.len() != 1 { > panic!("Expected a buffer of length one"); > } > PrefToken::Paren(buf.chars().next().unwrap(), position) >- }, >+ } > TokenType::Semicolon => PrefToken::Semicolon(position), > TokenType::Comma => PrefToken::Comma(position), > TokenType::String => PrefToken::String(buf, position), > TokenType::Int => { >- let value = i64::from_str_radix(buf.borrow(), 10) >- .expect("Integer wasn't parsed as an i64"); >+ let value = >+ i64::from_str_radix(buf.borrow(), 10).expect("Integer wasn't parsed as an i64"); > PrefToken::Int(value, position) >- }, >+ } > TokenType::Bool => { > let value = match buf.borrow() { > "true" => true, > "false" => false, >- x => panic!(format!("Boolean wasn't 'true' or 'false' (was {})", x)) >+ x => panic!(format!("Boolean wasn't 'true' or 'false' (was {})", x)), > }; > PrefToken::Bool(value, position) >- }, >- TokenType::Error => panic!("make_token can't construct errors") >+ } >+ TokenType::Error => panic!("make_token can't construct errors"), > } > } > > fn get_char(&mut self) -> Option<char> { > if self.pos >= self.data.len() - 1 { > self.cur = None; >- return None >+ return None; > }; > if self.cur.is_some() { > self.pos += 1; > } > let c = self.data[self.pos] as char; > if self.cur == Some('\n') { > self.position.line += 1; > self.position.column = 0; >@@ -295,26 +298,26 @@ impl<'a> PrefTokenizer<'a> { > self.cur = Some(c); > } > self.cur > } > > fn is_space(c: char) -> bool { > match c { > ' ' | '\t' | '\r' | '\n' => true, >- _ => false >+ _ => false, > } > } > > fn skip_whitespace(&mut self) -> Option<char> { > while let Some(c) = self.cur { > if PrefTokenizer::is_space(c) { > self.get_char(); > } else { >- break >+ break; > }; > } > self.cur > } > > fn consume_escape(&mut self, token_data: &mut TokenData<'a>) -> Result<(), PrefReaderError> { > let pos = self.pos; > let escaped = try!(self.read_escape()); >@@ -330,62 +333,84 @@ impl<'a> PrefTokenizer<'a> { > Some('u') => try!(self.read_hex_escape(4, true)), > Some('x') => try!(self.read_hex_escape(2, true)), > Some('\\') => '\\' as u32, > Some('"') => '"' as u32, > Some('\'') => '\'' as u32, > Some('r') => '\r' as u32, > Some('n') => '\n' as u32, > Some(_) => return Ok(None), >- None => return Err(PrefReaderError::new("EOF in character escape", >- self.position, None)) >+ None => { >+ return Err(PrefReaderError::new( >+ "EOF in character escape", >+ self.position, >+ None, >+ )) >+ } > }; >- Ok(Some(try!(char::from_u32(escape_char) >- .ok_or(PrefReaderError::new("Invalid codepoint decoded from escape", >- self.position, None))))) >+ Ok(Some(try!(char::from_u32(escape_char).ok_or( >+ PrefReaderError::new("Invalid codepoint decoded from escape", self.position, None) >+ )))) > } > > fn read_hex_escape(&mut self, hex_chars: isize, first: bool) -> Result<u32, PrefReaderError> { > let mut value = 0; > for _ in 0..hex_chars { > match self.get_char() { > Some(x) => { > value = value << 4; > match x { > '0'...'9' => value += x as u32 - '0' as u32, > 'a'...'f' => value += x as u32 - 'a' as u32, > 'A'...'F' => value += x as u32 - 'A' as u32, >- _ => return Err(PrefReaderError::new( >- "Unexpected character in escape", self.position, None)) >+ _ => { >+ return Err(PrefReaderError::new( >+ "Unexpected character in escape", >+ self.position, >+ None, >+ )) >+ } > } >- }, >- None => return Err(PrefReaderError::new( >- "Unexpected EOF in escape", self.position, None)) >+ } >+ None => { >+ return Err(PrefReaderError::new( >+ "Unexpected EOF in escape", >+ self.position, >+ None, >+ )) >+ } > } > } > if first && value >= 0xD800 && value <= 0xDBFF { > // First part of a surrogate pair > if self.get_char() != Some('\\') || self.get_char() != Some('u') { >- return Err(PrefReaderError::new("Lone high surrogate in surrogate pair", >- self.position, None)) >+ return Err(PrefReaderError::new( >+ "Lone high surrogate in surrogate pair", >+ self.position, >+ None, >+ )); > } > self.unget_char(); > let high_surrogate = value; > let low_surrogate = try!(self.read_hex_escape(4, false)); > let high_value = (high_surrogate - 0xD800) << 10; > let low_value = low_surrogate - 0xDC00; > value = high_value + low_value + 0x10000; > } else if first && value >= 0xDC00 && value <= 0xDFFF { >- return Err(PrefReaderError::new("Lone low surrogate", >- self.position, >- None)) >+ return Err(PrefReaderError::new( >+ "Lone low surrogate", >+ self.position, >+ None, >+ )); > } else if !first && (value < 0xDC00 || value > 0xDFFF) { >- return Err(PrefReaderError::new("Invalid low surrogate in surrogate pair", >- self.position, >- None)); >+ return Err(PrefReaderError::new( >+ "Invalid low surrogate in surrogate pair", >+ self.position, >+ None, >+ )); > } > Ok(value) > } > > fn get_match(&mut self, target: &str, separators: &str) -> bool { > let initial_pos = self.pos; > let mut matched = true; > for c in target.chars() { >@@ -415,300 +440,303 @@ impl<'a> PrefTokenizer<'a> { > } > > fn next_token(&mut self) -> Result<Option<TokenData<'a>>, PrefReaderError> { > let mut token_data = TokenData::new(TokenType::None, Position::new(), 0); > > loop { > let mut c = match self.get_char() { > Some(x) => x, >- None => return Ok(None) >+ None => return Ok(None), > }; > > self.state = match self.state { > TokenizerState::Junk => { > c = match self.skip_whitespace() { > Some(x) => x, >- None => return Ok(None) >+ None => return Ok(None), > }; > match c { > '/' => TokenizerState::CommentStart, > '#' => { > token_data.start(&self, TokenType::CommentBashLine); > token_data.start_pos = self.pos + 1; > TokenizerState::CommentLine >- }, >+ } > _ => { > self.unget_char(); > let next = match self.next_state { > Some(x) => x, > None => { > return Err(PrefReaderError::new( > "In Junk state without a next state defined", > self.position, >- None)) >+ None, >+ )) > } > }; > self.next_state = None; > next > } > } >+ } >+ TokenizerState::CommentStart => match c { >+ '*' => { >+ token_data.start(&self, TokenType::CommentBlock); >+ token_data.start_pos = self.pos + 1; >+ TokenizerState::CommentBlock >+ } >+ '/' => { >+ token_data.start(&self, TokenType::CommentLine); >+ token_data.start_pos = self.pos + 1; >+ TokenizerState::CommentLine >+ } >+ _ => { >+ return Err(PrefReaderError::new( >+ "Invalid character after /", >+ self.position, >+ None, >+ )) >+ } > }, >- TokenizerState::CommentStart => { >- match c { >- '*' => { >- token_data.start(&self, TokenType::CommentBlock); >- token_data.start_pos = self.pos + 1; >+ TokenizerState::CommentLine => match c { >+ '\n' => { >+ try!(token_data.end(&self.data, self.pos)); >+ TokenizerState::Junk >+ } >+ _ => TokenizerState::CommentLine, >+ }, >+ TokenizerState::CommentBlock => match c { >+ '*' => { >+ if self.get_char() == Some('/') { >+ try!(token_data.end(&self.data, self.pos - 1)); >+ TokenizerState::Junk >+ } else { > TokenizerState::CommentBlock >- }, >- '/' => { >- token_data.start(&self, TokenType::CommentLine); >- token_data.start_pos = self.pos + 1; >- TokenizerState::CommentLine >- }, >- _ => { >- return Err(PrefReaderError::new( >- "Invalid character after /", self.position, None)) > } > } >- >- }, >- TokenizerState::CommentLine => { >- match c { >- '\n' => { >- try!(token_data.end(&self.data, self.pos)); >- TokenizerState::Junk >- }, >- _ => { >- TokenizerState::CommentLine >- } >- } >- }, >- TokenizerState::CommentBlock => { >- match c { >- '*' => { >- if self.get_char() == Some('/') { >- try!(token_data.end(&self.data, self.pos - 1)); >- TokenizerState::Junk >- } else { >- TokenizerState::CommentBlock >- } >- }, >- _ => TokenizerState::CommentBlock >- } >+ _ => TokenizerState::CommentBlock, > }, > TokenizerState::FunctionName => { > let position = self.position; > let start_pos = self.pos; > match c { > 'u' => { > if self.get_match("user_pref", "(") { > token_data.start(&self, TokenType::UserPrefFunction); > } >- }, >+ } > 's' => { > if self.get_match("sticky_pref", "(") { > token_data.start(&self, TokenType::StickyPrefFunction); > } > } > 'p' => { > if self.get_match("pref", "(") { > token_data.start(&self, TokenType::PrefFunction); > } >- }, >+ } > _ => {} > }; > if token_data.token_type == TokenType::None { > // We didn't match anything > return Err(PrefReaderError::new( >- "Expected a pref function name", position, None)) >+ "Expected a pref function name", >+ position, >+ None, >+ )); > } else { > token_data.start_pos = start_pos; > token_data.position = position; > try!(token_data.end(&self.data, self.pos + 1)); > self.next_state = Some(TokenizerState::AfterFunctionName); > TokenizerState::Junk > } >- }, >- TokenizerState::AfterFunctionName => { >- match c { >- '(' => { >- self.next_state = Some(TokenizerState::FunctionArgs); >- token_data.start(&self, TokenType::Paren); >- try!(token_data.end(&self.data, self.pos + 1)); >- self.next_state = Some(TokenizerState::FunctionArgs); >- TokenizerState::Junk >- }, >- _ => { >- return Err(PrefReaderError::new( >- "Expected an opening paren", self.position, None)) >- } >+ } >+ TokenizerState::AfterFunctionName => match c { >+ '(' => { >+ self.next_state = Some(TokenizerState::FunctionArgs); >+ token_data.start(&self, TokenType::Paren); >+ try!(token_data.end(&self.data, self.pos + 1)); >+ self.next_state = Some(TokenizerState::FunctionArgs); >+ TokenizerState::Junk >+ } >+ _ => { >+ return Err(PrefReaderError::new( >+ "Expected an opening paren", >+ self.position, >+ None, >+ )) > } > }, >- TokenizerState::FunctionArgs => { >- match c { >- ')' => { >- token_data.start(&self, TokenType::Paren); >- try!(token_data.end(&self.data, self.pos + 1)); >- self.next_state = Some(TokenizerState::AfterFunction); >- TokenizerState::Junk >- }, >- _ => { >- self.unget_char(); >- TokenizerState::FunctionArg >- } >+ TokenizerState::FunctionArgs => match c { >+ ')' => { >+ token_data.start(&self, TokenType::Paren); >+ try!(token_data.end(&self.data, self.pos + 1)); >+ self.next_state = Some(TokenizerState::AfterFunction); >+ TokenizerState::Junk >+ } >+ _ => { >+ self.unget_char(); >+ TokenizerState::FunctionArg > } > }, >- TokenizerState::FunctionArg => { >- match c { >- '"' => { >- token_data.start(&self, TokenType::String); >- token_data.start_pos = self.pos + 1; >- TokenizerState::DoubleQuotedString >- }, >- '\'' => { >- token_data.start(&self, TokenType::String); >- token_data.start_pos = self.pos + 1; >- TokenizerState::SingleQuotedString >- }, >- 't' | 'f' => { >- self.unget_char(); >- TokenizerState::Bool >- }, >- '0'...'9' | '-' |'+' => { >- token_data.start(&self, TokenType::Int); >- TokenizerState::Number >- }, >- _ => { >- return Err(PrefReaderError::new( >- "Invalid character at start of function argument", >- self.position, None)) >- } >+ TokenizerState::FunctionArg => match c { >+ '"' => { >+ token_data.start(&self, TokenType::String); >+ token_data.start_pos = self.pos + 1; >+ TokenizerState::DoubleQuotedString >+ } >+ '\'' => { >+ token_data.start(&self, TokenType::String); >+ token_data.start_pos = self.pos + 1; >+ TokenizerState::SingleQuotedString >+ } >+ 't' | 'f' => { >+ self.unget_char(); >+ TokenizerState::Bool >+ } >+ '0'...'9' | '-' | '+' => { >+ token_data.start(&self, TokenType::Int); >+ TokenizerState::Number >+ } >+ _ => { >+ return Err(PrefReaderError::new( >+ "Invalid character at start of function argument", >+ self.position, >+ None, >+ )) > } > }, >- TokenizerState::DoubleQuotedString => { >- match c { >- '"' => { >- try!(token_data.end(&self.data, self.pos)); >- self.next_state = Some(TokenizerState::AfterFunctionArg); >- TokenizerState::Junk >- >- }, >- '\n' => { >- return Err(PrefReaderError::new( >- "EOL in double quoted string", self.position, None)) >- }, >- '\\' => { >- try!(self.consume_escape(&mut token_data)); >- TokenizerState::DoubleQuotedString >- }, >- _ => TokenizerState::DoubleQuotedString >+ TokenizerState::DoubleQuotedString => match c { >+ '"' => { >+ try!(token_data.end(&self.data, self.pos)); >+ self.next_state = Some(TokenizerState::AfterFunctionArg); >+ TokenizerState::Junk > } >+ '\n' => { >+ return Err(PrefReaderError::new( >+ "EOL in double quoted string", >+ self.position, >+ None, >+ )) >+ } >+ '\\' => { >+ try!(self.consume_escape(&mut token_data)); >+ TokenizerState::DoubleQuotedString >+ } >+ _ => TokenizerState::DoubleQuotedString, > }, >- TokenizerState::SingleQuotedString => { >- match c { >- '\'' => { >- try!(token_data.end(&self.data, self.pos)); >- self.next_state = Some(TokenizerState::AfterFunctionArg); >- TokenizerState::Junk >- >- }, >- '\n' => { >- return Err(PrefReaderError::new( >- "EOL in single quoted string", self.position, None)) >- }, >- '\\' => { >- try!(self.consume_escape(&mut token_data)); >- TokenizerState::SingleQuotedString >- } >- _ => TokenizerState::SingleQuotedString >+ TokenizerState::SingleQuotedString => match c { >+ '\'' => { >+ try!(token_data.end(&self.data, self.pos)); >+ self.next_state = Some(TokenizerState::AfterFunctionArg); >+ TokenizerState::Junk >+ } >+ '\n' => { >+ return Err(PrefReaderError::new( >+ "EOL in single quoted string", >+ self.position, >+ None, >+ )) > } >+ '\\' => { >+ try!(self.consume_escape(&mut token_data)); >+ TokenizerState::SingleQuotedString >+ } >+ _ => TokenizerState::SingleQuotedString, > }, >- TokenizerState::Number => { >- match c { >- '0'...'9' => TokenizerState::Number, >- ')' | ',' => { >- try!(token_data.end(&self.data, self.pos)); >- self.unget_char(); >- self.next_state = Some(TokenizerState::AfterFunctionArg); >- TokenizerState::Junk >- }, >- x if PrefTokenizer::is_space(x) => { >- try!(token_data.end(&self.data, self.pos)); >- self.next_state = Some(TokenizerState::AfterFunctionArg); >- TokenizerState::Junk >- }, >- _ => { >- return Err(PrefReaderError::new( >- "Invalid character in number literal", self.position, None)) >- } >+ TokenizerState::Number => match c { >+ '0'...'9' => TokenizerState::Number, >+ ')' | ',' => { >+ try!(token_data.end(&self.data, self.pos)); >+ self.unget_char(); >+ self.next_state = Some(TokenizerState::AfterFunctionArg); >+ TokenizerState::Junk >+ } >+ x if PrefTokenizer::is_space(x) => { >+ try!(token_data.end(&self.data, self.pos)); >+ self.next_state = Some(TokenizerState::AfterFunctionArg); >+ TokenizerState::Junk >+ } >+ _ => { >+ return Err(PrefReaderError::new( >+ "Invalid character in number literal", >+ self.position, >+ None, >+ )) > } > }, > TokenizerState::Bool => { > let start_pos = self.pos; > let position = self.position; > match c { > 't' => { > if self.get_match("true", ",)") { > token_data.start(&self, TokenType::Bool) > } >- }, >+ } > 'f' => { > if self.get_match("false", ",)") { > token_data.start(&self, TokenType::Bool) > } > } > _ => {} > }; > if token_data.token_type == TokenType::None { > return Err(PrefReaderError::new( > "Unexpected characters in function argument", >- position, None)); >+ position, >+ None, >+ )); > } else { > token_data.start_pos = start_pos; > token_data.position = position; > try!(token_data.end(&self.data, self.pos + 1)); > self.next_state = Some(TokenizerState::AfterFunctionArg); > TokenizerState::Junk > } >- }, >- TokenizerState::AfterFunctionArg => { >- match c { >- ',' => { >- token_data.start(&self, TokenType::Comma); >- try!(token_data.end(&self.data, self.pos + 1)); >- self.next_state = Some(TokenizerState::FunctionArg); >- TokenizerState::Junk >- } >- ')' => { >- token_data.start(&self, TokenType::Paren); >- try!(token_data.end(&self.data, self.pos + 1)); >- self.next_state = Some(TokenizerState::AfterFunction); >- TokenizerState::Junk >- } >- _ => return Err(PrefReaderError::new >- ("Unexpected character after function argument", >- self.position, >- None)) >+ } >+ TokenizerState::AfterFunctionArg => match c { >+ ',' => { >+ token_data.start(&self, TokenType::Comma); >+ try!(token_data.end(&self.data, self.pos + 1)); >+ self.next_state = Some(TokenizerState::FunctionArg); >+ TokenizerState::Junk >+ } >+ ')' => { >+ token_data.start(&self, TokenType::Paren); >+ try!(token_data.end(&self.data, self.pos + 1)); >+ self.next_state = Some(TokenizerState::AfterFunction); >+ TokenizerState::Junk >+ } >+ _ => { >+ return Err(PrefReaderError::new( >+ "Unexpected character after function argument", >+ self.position, >+ None, >+ )) > } > }, >- TokenizerState::AfterFunction => { >- match c { >- ';' => { >- token_data.start(&self, TokenType::Semicolon); >- try!(token_data.end(&self.data, self.pos)); >- self.next_state = Some(TokenizerState::FunctionName); >- TokenizerState::Junk >- } >- _ => return Err(PrefReaderError::new( >+ TokenizerState::AfterFunction => match c { >+ ';' => { >+ token_data.start(&self, TokenType::Semicolon); >+ try!(token_data.end(&self.data, self.pos)); >+ self.next_state = Some(TokenizerState::FunctionName); >+ TokenizerState::Junk >+ } >+ _ => { >+ return Err(PrefReaderError::new( > "Unexpected character after function", >- self.position, None)) >+ self.position, >+ None, >+ )) > } > }, >- TokenizerState::Error => TokenizerState::Error >+ TokenizerState::Error => TokenizerState::Error, > }; > if token_data.complete { > return Ok(Some(token_data)); > } > } > } > } > >@@ -717,20 +745,18 @@ impl<'a> Iterator for PrefTokenizer<'a> { > > fn next(&mut self) -> Option<PrefToken<'a>> { > if let TokenizerState::Error = self.state { > return None; > } > let token_data = match self.next_token() { > Err(e) => { > self.state = TokenizerState::Error; >- return Some(PrefToken::Error(e.message, >- e.position)) >- >- }, >+ return Some(PrefToken::Error(e.message, e.position)); >+ } > Ok(Some(token_data)) => token_data, > Ok(None) => return None, > }; > let token = self.make_token(token_data); > Some(token) > } > } > >@@ -746,232 +772,252 @@ pub fn serialize_token<T: Write>(token: &PrefToken, output: &mut T) -> Result<() > &PrefToken::UserPrefFunction(_) => "user_pref", > &PrefToken::StickyPrefFunction(_) => "sticky_pref", > &PrefToken::CommentBlock(ref data, _) => { > data_buf.reserve(data.len() + 4); > data_buf.push_str("/*"); > data_buf.push_str(data.borrow()); > data_buf.push_str("*"); > &*data_buf >- }, >+ } > &PrefToken::CommentLine(ref data, _) => { > data_buf.reserve(data.len() + 2); > data_buf.push_str("//"); > data_buf.push_str(data.borrow()); > &*data_buf >- }, >+ } > &PrefToken::CommentBashLine(ref data, _) => { > data_buf.reserve(data.len() + 1); > data_buf.push_str("#"); > data_buf.push_str(data.borrow()); > &*data_buf >- }, >+ } > &PrefToken::Paren(data, _) => { > data_buf.push(data); > &*data_buf >- }, >+ } > &PrefToken::Comma(_) => ",", > &PrefToken::Semicolon(_) => ";\n", > &PrefToken::String(ref data, _) => { > data_buf.reserve(data.len() + 2); > data_buf.push('"'); > data_buf.push_str(escape_quote(data.borrow()).borrow()); > data_buf.push('"'); > &*data_buf >- }, >+ } > &PrefToken::Int(data, _) => { > data_buf.push_str(&*data.to_string()); > &*data_buf >- }, >+ } > &PrefToken::Bool(data, _) => { >- if data {"true"} else {"false"} >- }, >- &PrefToken::Error(data, pos) => return Err(PrefReaderError::new(data, pos, None)) >+ if data { >+ "true" >+ } else { >+ "false" >+ } >+ } >+ &PrefToken::Error(data, pos) => return Err(PrefReaderError::new(data, pos, None)), > }; > try!(output.write(data.as_bytes())); > Ok(()) > } > > pub fn serialize_tokens<'a, I, W>(tokens: I, output: &mut W) -> Result<(), PrefReaderError> >- where I: Iterator<Item=&'a PrefToken<'a>>, W: Write { >+where >+ I: Iterator<Item = &'a PrefToken<'a>>, >+ W: Write, >+{ > for token in tokens { > try!(serialize_token(token, output)); > } > Ok(()) > } > > fn escape_quote<'a>(data: &'a str) -> Cow<'a, str> { > // Not very efficient⦠> if data.contains("\"") || data.contains("\\") { >- let new_data = Cow::Owned(data >- .replace(r#"\"#, r#"\\"#) >- .replace(r#"""#, r#"\""#)); >+ let new_data = Cow::Owned(data.replace(r#"\"#, r#"\\"#).replace(r#"""#, r#"\""#)); > new_data > } else { > Cow::Borrowed(data) > } > } > > #[derive(Debug, PartialEq)] > enum ParserState { > Function, > Key, > Value, > } > > struct PrefBuilder { > key: Option<String>, > value: Option<PrefValue>, >- sticky: bool >+ sticky: bool, > } > > impl PrefBuilder { > fn new() -> PrefBuilder { > PrefBuilder { > key: None, > value: None, >- sticky: false >+ sticky: false, > } > } > } > >- > fn skip_comments<'a>(tokenizer: &mut PrefTokenizer<'a>) -> Option<PrefToken<'a>> { > loop { > match tokenizer.next() { >- Some(PrefToken::CommentBashLine(_, _)) | >- Some(PrefToken::CommentBlock(_, _)) | >- Some(PrefToken::CommentLine(_, _)) => {}, >+ Some(PrefToken::CommentBashLine(_, _)) >+ | Some(PrefToken::CommentBlock(_, _)) >+ | Some(PrefToken::CommentLine(_, _)) => {} > Some(x) => return Some(x), > None => return None, > } > } > } > >-pub fn parse_tokens<'a>(tokenizer: &mut PrefTokenizer<'a>) -> Result<Preferences, >- PrefReaderError> { >- >+pub fn parse_tokens<'a>(tokenizer: &mut PrefTokenizer<'a>) -> Result<Preferences, PrefReaderError> { > let mut state = ParserState::Function; > let mut current_pref = PrefBuilder::new(); > let mut rv = Preferences::new(); > > loop { > // Not just using a for loop here seems strange, but this restricts the > // scope of the borrow > let token = { > match tokenizer.next() { > Some(x) => x, >- None => break >+ None => break, > } > }; > // First deal with comments and errors > match token { > PrefToken::Error(msg, position) => { > return Err(PrefReaderError::new(msg.into(), position, None)); >- }, >- PrefToken::CommentBashLine(_, _) | >- PrefToken::CommentLine(_, _) | >- PrefToken::CommentBlock(_, _) => { >- continue >- }, >+ } >+ PrefToken::CommentBashLine(_, _) >+ | PrefToken::CommentLine(_, _) >+ | PrefToken::CommentBlock(_, _) => continue, > _ => {} > } > state = match state { > ParserState::Function => { > match token { > PrefToken::PrefFunction(_) => { > current_pref.sticky = false; > } > PrefToken::UserPrefFunction(_) => { > current_pref.sticky = false; >- }, >+ } > PrefToken::StickyPrefFunction(_) => { > current_pref.sticky = true; >- }, >+ } > _ => { >- return Err(PrefReaderError::new("Expected pref function".into(), >- token.position(), None)); >+ return Err(PrefReaderError::new( >+ "Expected pref function".into(), >+ token.position(), >+ None, >+ )); > } > } > let next = skip_comments(tokenizer); > match next { > Some(PrefToken::Paren('(', _)) => ParserState::Key, >- _ => return Err(PrefReaderError::new("Expected open paren".into(), >- next.map(|x| x.position()) >- .unwrap_or(tokenizer.position), >- None)) >+ _ => { >+ return Err(PrefReaderError::new( >+ "Expected open paren".into(), >+ next.map(|x| x.position()).unwrap_or(tokenizer.position), >+ None, >+ )) >+ } > } >- }, >+ } > ParserState::Key => { > match token { > PrefToken::String(data, _) => current_pref.key = Some(data.into_owned()), > _ => { >- return Err(PrefReaderError::new("Expected string", token.position(), None)); >+ return Err(PrefReaderError::new( >+ "Expected string", >+ token.position(), >+ None, >+ )); > } > } > let next = skip_comments(tokenizer); > match next { > Some(PrefToken::Comma(_)) => ParserState::Value, >- _ => return Err(PrefReaderError::new("Expected comma", >- next.map(|x| x.position()) >- .unwrap_or(tokenizer.position), >- None)) >+ _ => { >+ return Err(PrefReaderError::new( >+ "Expected comma", >+ next.map(|x| x.position()).unwrap_or(tokenizer.position), >+ None, >+ )) >+ } > } >- }, >+ } > ParserState::Value => { > match token { > PrefToken::String(data, _) => { > current_pref.value = Some(PrefValue::String(data.into_owned())) >- }, >- PrefToken::Int(data, _) => { >- current_pref.value = Some(PrefValue::Int(data)) > } >- PrefToken::Bool(data, _) => { >- current_pref.value = Some(PrefValue::Bool(data)) >- }, >+ PrefToken::Int(data, _) => current_pref.value = Some(PrefValue::Int(data)), >+ PrefToken::Bool(data, _) => current_pref.value = Some(PrefValue::Bool(data)), > _ => { >- return Err(PrefReaderError::new("Expected value", token.position(), >- None)) >+ return Err(PrefReaderError::new( >+ "Expected value", >+ token.position(), >+ None, >+ )) > } > } > let next = skip_comments(tokenizer); > match next { > Some(PrefToken::Paren(')', _)) => {} >- _ => return Err(PrefReaderError::new("Expected close paren", >- next.map(|x| x.position()) >- .unwrap_or(tokenizer.position), >- None)) >+ _ => { >+ return Err(PrefReaderError::new( >+ "Expected close paren", >+ next.map(|x| x.position()).unwrap_or(tokenizer.position), >+ None, >+ )) >+ } > } > let next = skip_comments(tokenizer); > match next { >- Some(PrefToken::Semicolon(_)) | >- None => {}, >- _ => return Err(PrefReaderError::new("Expected semicolon", >- next.map(|x| x.position()) >- .unwrap_or(tokenizer.position), >- None)) >+ Some(PrefToken::Semicolon(_)) | None => {} >+ _ => { >+ return Err(PrefReaderError::new( >+ "Expected semicolon", >+ next.map(|x| x.position()).unwrap_or(tokenizer.position), >+ None, >+ )) >+ } > } > let key = mem::replace(&mut current_pref.key, None); > let value = mem::replace(&mut current_pref.value, None); > let pref = if current_pref.sticky { > Pref::new_sticky(value.unwrap()) > } else { > Pref::new(value.unwrap()) > }; > rv.insert(key.unwrap(), pref); > current_pref.sticky = false; > ParserState::Function >- }, >+ } > } > } > match state { > ParserState::Key | ParserState::Value => { >- return Err(PrefReaderError::new("EOF in middle of function", >- tokenizer.position, None)); >- }, >+ return Err(PrefReaderError::new( >+ "EOF in middle of function", >+ tokenizer.position, >+ None, >+ )); >+ } > _ => {} > } > Ok(rv) > } > > pub fn serialize<W: Write>(prefs: &Preferences, output: &mut W) -> io::Result<()> { > let mut p: Vec<_> = prefs.iter().collect(); > p.sort_by(|a, b| a.0.cmp(&b.0)); >@@ -983,28 +1029,28 @@ pub fn serialize<W: Write>(prefs: &Preferences, output: &mut W) -> io::Result<() > }.as_bytes(); > try!(output.write(func)); > try!(output.write("\"".as_bytes())); > try!(output.write(escape_quote(key).as_bytes())); > try!(output.write("\"".as_bytes())); > try!(output.write(", ".as_bytes())); > match pref.value { > PrefValue::Bool(x) => { >- try!(output.write((if x {"true"} else {"false"}).as_bytes())); >- }, >+ try!(output.write((if x { "true" } else { "false" }).as_bytes())); >+ } > PrefValue::Int(x) => { > try!(output.write(x.to_string().as_bytes())); >- }, >+ } > PrefValue::String(ref x) => { > try!(output.write("\"".as_bytes())); > try!(output.write(escape_quote(x).as_bytes())); > try!(output.write("\"".as_bytes())); > } > }; > try!(output.write(");\n".as_bytes())); >- }; >+ } > Ok(()) > } > > pub fn parse<'a>(data: &'a [u8]) -> Result<Preferences, PrefReaderError> { > let mut tokenizer = tokenize(data); > parse_tokens(&mut tokenizer) > } >diff --git a/testing/mozbase/rust/mozprofile/src/profile.rs b/testing/mozbase/rust/mozprofile/src/profile.rs >index d38f50d1fde6..87205d7db3de 100644 >--- a/testing/mozbase/rust/mozprofile/src/profile.rs >+++ b/testing/mozbase/rust/mozprofile/src/profile.rs >@@ -1,14 +1,14 @@ >-use preferences::{Preferences, Pref}; >+use preferences::{Pref, Preferences}; > use prefreader::{parse, serialize, PrefReaderError}; > use std::collections::btree_map::Iter; > use std::fs::File; >-use std::io::Result as IoResult; > use std::io::prelude::*; >+use std::io::Result as IoResult; > use std::path::{Path, PathBuf}; > use tempdir::TempDir; > > #[derive(Debug)] > pub struct Profile { > pub path: PathBuf, > pub temp_dir: Option<TempDir>, > prefs: Option<PrefFile>, >@@ -27,17 +27,17 @@ impl Profile { > temp_path > } > }; > > Ok(Profile { > path: path, > temp_dir: temp_dir, > prefs: None, >- user_prefs: None >+ user_prefs: None, > }) > } > > pub fn prefs(&mut self) -> Result<&mut PrefFile, PrefReaderError> { > if self.prefs.is_none() { > let mut pref_path = PathBuf::from(&self.path); > pref_path.push("prefs.js"); > self.prefs = Some(try!(PrefFile::new(pref_path))) >@@ -71,34 +71,38 @@ impl PrefFile { > let mut f = try!(File::open(&path)); > let mut buf = String::with_capacity(4096); > try!(f.read_to_string(&mut buf)); > try!(parse(buf.as_bytes())) > }; > > Ok(PrefFile { > path: path, >- prefs: prefs >+ prefs: prefs, > }) > } > > pub fn write(&self) -> IoResult<()> { > let mut f = try!(File::create(&self.path)); > serialize(&self.prefs, &mut f) > } > > pub fn insert_slice<K>(&mut self, preferences: &[(K, Pref)]) >- where K: Into<String> + Clone { >+ where >+ K: Into<String> + Clone, >+ { > for &(ref name, ref value) in preferences.iter() { > self.insert((*name).clone(), (*value).clone()); > } > } > > pub fn insert<K>(&mut self, key: K, value: Pref) >- where K: Into<String> { >+ where >+ K: Into<String>, >+ { > self.prefs.insert(key.into(), value); > } > > pub fn remove(&mut self, key: &str) -> Option<Pref> { > self.prefs.remove(key) > } > > pub fn get(&mut self, key: &str) -> Option<&Pref> { >diff --git a/testing/mozbase/rust/mozrunner/src/bin/firefox-default-path.rs b/testing/mozbase/rust/mozrunner/src/bin/firefox-default-path.rs >index 39588b809902..adee6a8015e9 100644 >--- a/testing/mozbase/rust/mozrunner/src/bin/firefox-default-path.rs >+++ b/testing/mozbase/rust/mozrunner/src/bin/firefox-default-path.rs >@@ -5,13 +5,13 @@ use std::io::Write; > > fn main() { > let (path, code) = platform::firefox_default_path() > .map(|x| (x.to_string_lossy().into_owned(), 0)) > .unwrap_or(("Firefox binary not found".to_owned(), 1)); > > let mut writer: Box<Write> = match code { > 0 => Box::new(std::io::stdout()), >- _ => Box::new(std::io::stderr()) >+ _ => Box::new(std::io::stderr()), > }; > writeln!(&mut writer, "{}", &*path).unwrap(); > std::process::exit(code); > } >diff --git a/testing/mozbase/rust/mozrunner/src/firefox_args.rs b/testing/mozbase/rust/mozrunner/src/firefox_args.rs >index b3acff195ef6..8a832e99718c 100644 >--- a/testing/mozbase/rust/mozrunner/src/firefox_args.rs >+++ b/testing/mozbase/rust/mozrunner/src/firefox_args.rs >@@ -92,24 +92,24 @@ impl<'a> From<&'a OsString> for Arg { > "profile" => Arg::Profile, > "P" => Arg::NamedProfile, > "ProfileManager" => Arg::ProfileManager, > "foreground" => Arg::Foreground, > "no-remote" => Arg::NoRemote, > _ => Arg::Other(basename), > } > } else { >- Arg::None >+ Arg::None > } > } > } > > #[cfg(test)] > mod tests { >- use super::{Arg, parse_arg_name}; >+ use super::{parse_arg_name, Arg}; > use std::ffi::OsString; > > fn parse(arg: &str, name: Option<&str>) { > let result = parse_arg_name(arg); > assert_eq!(result, name.map(|x| x.to_string())); > } > > #[test] >@@ -147,24 +147,36 @@ mod tests { > parse("/profile", None); > } > > #[test] > fn test_arg_from_osstring() { > assert_eq!(Arg::from(&OsString::from("-- profile")), Arg::None); > assert_eq!(Arg::from(&OsString::from("profile")), Arg::None); > assert_eq!(Arg::from(&OsString::from("profile -P")), Arg::None); >- assert_eq!(Arg::from(&OsString::from("-profiled")), Arg::Other("profiled".into())); >- assert_eq!(Arg::from(&OsString::from("-PROFILEMANAGER")), Arg::Other("PROFILEMANAGER".into())); >+ assert_eq!( >+ Arg::from(&OsString::from("-profiled")), >+ Arg::Other("profiled".into()) >+ ); >+ assert_eq!( >+ Arg::from(&OsString::from("-PROFILEMANAGER")), >+ Arg::Other("PROFILEMANAGER".into()) >+ ); > > assert_eq!(Arg::from(&OsString::from("--profile")), Arg::Profile); > assert_eq!(Arg::from(&OsString::from("-profile foo")), Arg::Profile); > >- assert_eq!(Arg::from(&OsString::from("--ProfileManager")), Arg::ProfileManager); >- assert_eq!(Arg::from(&OsString::from("-ProfileManager")), Arg::ProfileManager); >+ assert_eq!( >+ Arg::from(&OsString::from("--ProfileManager")), >+ Arg::ProfileManager >+ ); >+ assert_eq!( >+ Arg::from(&OsString::from("-ProfileManager")), >+ Arg::ProfileManager >+ ); > > // TODO: -Ptest is valid > //assert_eq!(Arg::from(&OsString::from("-Ptest")), Arg::NamedProfile); > assert_eq!(Arg::from(&OsString::from("-P")), Arg::NamedProfile); > assert_eq!(Arg::from(&OsString::from("-P test")), Arg::NamedProfile); > > assert_eq!(Arg::from(&OsString::from("--foreground")), Arg::Foreground); > assert_eq!(Arg::from(&OsString::from("-foreground")), Arg::Foreground); >diff --git a/testing/mozbase/rust/mozrunner/src/runner.rs b/testing/mozbase/rust/mozrunner/src/runner.rs >index 11a627182209..ced02f2f0f84 100644 >--- a/testing/mozbase/rust/mozrunner/src/runner.rs >+++ b/testing/mozbase/rust/mozrunner/src/runner.rs >@@ -91,22 +91,20 @@ impl fmt::Display for RunnerError { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > self.description().fmt(f) > } > } > > impl Error for RunnerError { > fn description(&self) -> &str { > match *self { >- RunnerError::Io(ref err) => { >- match err.kind() { >- ErrorKind::NotFound => "no such file or directory", >- _ => err.description(), >- } >- } >+ RunnerError::Io(ref err) => match err.kind() { >+ ErrorKind::NotFound => "no such file or directory", >+ _ => err.description(), >+ }, > RunnerError::PrefReader(ref err) => err.description(), > } > } > > fn cause(&self) -> Option<&Error> { > Some(match *self { > RunnerError::Io(ref err) => err as &Error, > RunnerError::PrefReader(ref err) => err as &Error, >@@ -267,17 +265,17 @@ impl Runner for FirefoxRunner { > let mut seen_foreground = false; > let mut seen_no_remote = false; > let mut seen_profile = false; > for arg in self.args.iter() { > match arg.into() { > Arg::Foreground => seen_foreground = true, > Arg::NoRemote => seen_no_remote = true, > Arg::Profile | Arg::NamedProfile | Arg::ProfileManager => seen_profile = true, >- Arg::Other(_) | Arg::None => {}, >+ Arg::Other(_) | Arg::None => {} > } > } > if !seen_foreground { > cmd.arg("-foreground"); > } > if !seen_no_remote { > cmd.arg("-no-remote"); > } >@@ -325,17 +323,18 @@ pub mod platform { > > let home = env::home_dir(); > for &(prefix_home, trial_path) in [ > ( > false, > "/Applications/Firefox.app/Contents/MacOS/firefox-bin", > ), > (true, "Applications/Firefox.app/Contents/MacOS/firefox-bin"), >- ].iter() >+ ] >+ .iter() > { > let path = match (home.as_ref(), prefix_home) { > (Some(ref home_dir), true) => home_dir.join(trial_path), > (None, true) => continue, > (_, false) => PathBuf::from(trial_path), > }; > if is_binary(&path) { > return Some(path); >@@ -350,18 +349,18 @@ pub mod platform { > } > } > > #[cfg(target_os = "windows")] > pub mod platform { > use path::{find_binary, is_binary}; > use std::io::Error; > use std::path::PathBuf; >- use winreg::RegKey; > use winreg::enums::*; >+ use winreg::RegKey; > > /// Searches the Windows registry, then the system path for `firefox.exe`. > /// > /// It _does not_ currently check the `HKEY_CURRENT_USER` tree. > pub fn firefox_default_path() -> Option<PathBuf> { > if let Ok(Some(path)) = firefox_registry_path() { > if is_binary(&path) { > return Some(path); >@@ -369,17 +368,18 @@ pub mod platform { > }; > find_binary("firefox.exe") > } > > fn firefox_registry_path() -> Result<Option<PathBuf>, Error> { > let hklm = RegKey::predef(HKEY_LOCAL_MACHINE); > for subtree_key in ["SOFTWARE", "SOFTWARE\\WOW6432Node"].iter() { > let subtree = hklm.open_subkey_with_flags(subtree_key, KEY_READ)?; >- let mozilla_org = match subtree.open_subkey_with_flags("mozilla.org\\Mozilla", KEY_READ) { >+ let mozilla_org = match subtree.open_subkey_with_flags("mozilla.org\\Mozilla", KEY_READ) >+ { > Ok(val) => val, > Err(_) => continue, > }; > let current_version: String = mozilla_org.get_value("CurrentVersion")?; > let mozilla = subtree.open_subkey_with_flags("Mozilla", KEY_READ)?; > for key_res in mozilla.enum_keys() { > let key = key_res?; > let section_data = mozilla.open_subkey_with_flags(&key, KEY_READ)?; >@@ -404,17 +404,21 @@ pub mod platform { > Ok(None) > } > > pub fn arg_prefix_char(c: char) -> bool { > c == '/' || c == '-' > } > } > >-#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] >+#[cfg(not(any( >+ target_os = "linux", >+ target_os = "macos", >+ target_os = "windows" >+)))] > pub mod platform { > use std::path::PathBuf; > > /// Returns `None` for all other operating systems than Linux, macOS, and > /// Windows. > pub fn firefox_default_path() -> Option<PathBuf> { > None > } >diff --git a/testing/mozbase/rust/mozversion/src/lib.rs b/testing/mozbase/rust/mozversion/src/lib.rs >index 07fab5e37bc1..262dbdd462ca 100644 >--- a/testing/mozbase/rust/mozversion/src/lib.rs >+++ b/testing/mozbase/rust/mozversion/src/lib.rs >@@ -1,15 +1,15 @@ > extern crate ini; > extern crate regex; > extern crate semver; > > use ini::Ini; >-use regex::Regex; > use platform::ini_path; >+use regex::Regex; > use std::default::Default; > use std::error; > use std::fmt::{self, Display, Formatter}; > use std::path::Path; > use std::str::FromStr; > > /// Details about the version of a Firefox build. > #[derive(Clone, Default)] >@@ -88,45 +88,59 @@ pub struct Version { > pub pre: Option<(String, u64)>, > } > > impl Version { > pub fn from_str(version_string: &str) -> Result<Version, Error> { > let mut version: Version = Default::default(); > let version_re = Regex::new(r"^(?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?(?:(?P<pre0>[a-z]+)(?P<pre1>\d*))?$").unwrap(); > if let Some(captures) = version_re.captures(version_string) { >- match captures.name("major") >- .and_then(|x| u64::from_str(x.as_str()).ok()) { >- Some(x) => version.major = x, >- None => return Err(Error::VersionError("No major version number found".into())) >- } >- match captures.name("minor") >- .and_then(|x| u64::from_str(x.as_str()).ok()) { >- Some(x) => version.minor = x, >- None => return Err(Error::VersionError("No minor version number found".into())) >- } >- match captures.name("patch") >- .and_then(|x| u64::from_str(x.as_str()).ok()) { >- Some(x) => version.patch = x, >- None => {} >- } >+ match captures >+ .name("major") >+ .and_then(|x| u64::from_str(x.as_str()).ok()) >+ { >+ Some(x) => version.major = x, >+ None => return Err(Error::VersionError("No major version number found".into())), >+ } >+ match captures >+ .name("minor") >+ .and_then(|x| u64::from_str(x.as_str()).ok()) >+ { >+ Some(x) => version.minor = x, >+ None => return Err(Error::VersionError("No minor version number found".into())), >+ } >+ match captures >+ .name("patch") >+ .and_then(|x| u64::from_str(x.as_str()).ok()) >+ { >+ Some(x) => version.patch = x, >+ None => {} >+ } > if let Some(pre_0) = captures.name("pre0").map(|x| x.as_str().to_string()) { > if captures.name("pre1").is_some() { >- if let Some(pre_1) = captures.name("pre1") >- .and_then(|x| u64::from_str(x.as_str()).ok()) { >- version.pre = Some((pre_0, pre_1)) >- } else { >- return Err(Error::VersionError("Failed to convert prelease number to u64".into())); >- } >+ if let Some(pre_1) = captures >+ .name("pre1") >+ .and_then(|x| u64::from_str(x.as_str()).ok()) >+ { >+ version.pre = Some((pre_0, pre_1)) >+ } else { >+ return Err(Error::VersionError( >+ "Failed to convert prelease number to u64".into(), >+ )); >+ } > } else { >- return Err(Error::VersionError("Failed to convert prelease number to u64".into())); >+ return Err(Error::VersionError( >+ "Failed to convert prelease number to u64".into(), >+ )); > } > } > } else { >- return Err(Error::VersionError("Failed to parse input as version string".into())) >+ return Err(Error::VersionError( >+ "Failed to parse input as version string".into(), >+ )); > } > Ok(version) > } > > fn to_semver(&self) -> semver::Version { > // The way the semver crate handles prereleases isn't what we want here > // This should be fixed in the long term by implementing our own comparison > // operators, but for now just act as if prerelease metadata was missing, otherwise >@@ -145,31 +159,31 @@ impl Version { > Ok(req.matches(&self.to_semver())) > } > } > > impl Display for Version { > fn fmt(&self, f: &mut Formatter) -> fmt::Result { > match self.patch { > 0 => try!(write!(f, "{}.{}", self.major, self.minor)), >- _ => try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch)) >+ _ => try!(write!(f, "{}.{}.{}", self.major, self.minor, self.patch)), > } > if let Some(ref pre) = self.pre { > try!(write!(f, "{}{}", pre.0, pre.1)); > }; > Ok(()) > } > } > > /// Determine the version of Firefox given the path to a binary. > /// > /// Given the path to a Firefox binary, read the associated application.ini > /// and platform.ini files to extract information about the version of Firefox > /// at that path. >-pub fn firefox_version(binary: &Path) -> Result<AppVersion, Error> { >+pub fn firefox_version(binary: &Path) -> Result<AppVersion, Error> { > let mut version = AppVersion::new(); > let mut updated = false; > > if let Some(dir) = ini_path(binary) { > let mut application_ini = dir.clone(); > application_ini.push("application.ini"); > > if Path::exists(&application_ini) { >@@ -187,45 +201,47 @@ pub fn firefox_version(binary: &Path) -> Result<AppVersion, Error> { > let ini_file = Ini::load_from_file(platform_ini).ok(); > if let Some(ini) = ini_file { > updated = true; > version.update_from_platform_ini(&ini); > } > } > > if !updated { >- return Err(Error::MetadataError("Neither platform.ini nor application.ini found".into())) >+ return Err(Error::MetadataError( >+ "Neither platform.ini nor application.ini found".into(), >+ )); > } > } else { >- return Err(Error::MetadataError("Invalid binary path".into())) >+ return Err(Error::MetadataError("Invalid binary path".into())); > } > Ok(version) > } > > #[derive(Debug)] > pub enum Error { > /// Error parsing a version string > VersionError(String), > /// Error reading application metadata > MetadataError(String), > /// Error processing a string as a semver comparator >- SemVerError(semver::ReqParseError) >+ SemVerError(semver::ReqParseError), > } > > impl Display for Error { > fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { > match self { > &Error::VersionError(ref x) => { > try!("VersionError: ".fmt(f)); > x.fmt(f) >- }, >+ } > &Error::MetadataError(ref x) => { > try!("MetadataError: ".fmt(f)); > x.fmt(f) >- }, >+ } > &Error::SemVerError(ref e) => { > try!("SemVerError: ".fmt(f)); > e.fmt(f) > } > } > } > } > >@@ -252,39 +268,43 @@ impl error::Error for Error { > } > } > > #[cfg(target_os = "macos")] > mod platform { > use std::path::{Path, PathBuf}; > > pub fn ini_path(binary: &Path) -> Option<PathBuf> { >- binary.canonicalize().ok() >+ binary >+ .canonicalize() >+ .ok() > .as_ref() > .and_then(|dir| dir.parent()) > .and_then(|dir| dir.parent()) > .map(|dir| dir.join("Resources")) > } > } > > #[cfg(not(target_os = "macos"))] > mod platform { > use std::path::{Path, PathBuf}; > > pub fn ini_path(binary: &Path) -> Option<PathBuf> { >- binary.canonicalize().ok() >+ binary >+ .canonicalize() >+ .ok() > .as_ref() > .and_then(|dir| dir.parent()) > .map(|dir| dir.to_path_buf()) > } > } > > #[cfg(test)] > mod test { >- use super::{Version}; >+ use super::Version; > > fn parse_version(input: &str) -> String { > Version::from_str(input).unwrap().to_string() > } > > fn compare(version: &str, comparison: &str) -> bool { > let v = Version::from_str(version).unwrap(); > v.matches(comparison).unwrap() >diff --git a/testing/webdriver/src/actions.rs b/testing/webdriver/src/actions.rs >index 22618e80660b..8adb7daacacd 100644 >--- a/testing/webdriver/src/actions.rs >+++ b/testing/webdriver/src/actions.rs >@@ -1,127 +1,149 @@ > use command::Parameters; > use common::{Nullable, WebElement}; >-use error::{WebDriverResult, WebDriverError, ErrorStatus}; >-use rustc_serialize::json::{ToJson, Json}; >-use unicode_segmentation::UnicodeSegmentation; >+use error::{ErrorStatus, WebDriverError, WebDriverResult}; >+use rustc_serialize::json::{Json, ToJson}; > use std::collections::BTreeMap; > use std::default::Default; >+use unicode_segmentation::UnicodeSegmentation; > > #[derive(Debug, PartialEq)] > pub struct ActionSequence { > pub id: Nullable<String>, >- pub actions: ActionsType >+ pub actions: ActionsType, > } > > impl Parameters for ActionSequence { > fn from_json(body: &Json) -> WebDriverResult<ActionSequence> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Actions chain was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Actions chain was not an object" >+ ); > >- let type_name = try_opt!(try_opt!(data.get("type"), >- ErrorStatus::InvalidArgument, >- "Missing type parameter").as_string(), >- ErrorStatus::InvalidArgument, >- "Parameter ;type' was not a string"); >+ let type_name = try_opt!( >+ try_opt!( >+ data.get("type"), >+ ErrorStatus::InvalidArgument, >+ "Missing type parameter" >+ ).as_string(), >+ ErrorStatus::InvalidArgument, >+ "Parameter ;type' was not a string" >+ ); > > let id = match data.get("id") { >- Some(x) => Some(try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "Parameter 'id' was not a string").to_owned()), >- None => None >+ Some(x) => Some( >+ try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'id' was not a string" >+ ).to_owned(), >+ ), >+ None => None, > }; > >- > // Note that unlike the spec we get the pointer parameters in ActionsType::from_json > > let actions = match type_name { > "none" | "key" | "pointer" => try!(ActionsType::from_json(&body)), >- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Invalid action type")) >+ _ => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Invalid action type", >+ )) >+ } > }; > > Ok(ActionSequence { > id: id.into(), >- actions: actions >+ actions: actions, > }) > } > } > > impl ToJson for ActionSequence { > fn to_json(&self) -> Json { > let mut data: BTreeMap<String, Json> = BTreeMap::new(); > data.insert("id".into(), self.id.to_json()); > let (action_type, actions) = match self.actions { >- ActionsType::Null(ref actions) => { >- ("none", >- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>()) >- } >- ActionsType::Key(ref actions) => { >- ("key", >- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>()) >- } >+ ActionsType::Null(ref actions) => ( >+ "none", >+ actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>(), >+ ), >+ ActionsType::Key(ref actions) => ( >+ "key", >+ actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>(), >+ ), > ActionsType::Pointer(ref parameters, ref actions) => { > data.insert("parameters".into(), parameters.to_json()); >- ("pointer", >- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>()) >+ ( >+ "pointer", >+ actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>(), >+ ) > } > }; > data.insert("type".into(), action_type.to_json()); > data.insert("actions".into(), actions.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub enum ActionsType { > Null(Vec<NullActionItem>), > Key(Vec<KeyActionItem>), >- Pointer(PointerActionParameters, Vec<PointerActionItem>) >+ Pointer(PointerActionParameters, Vec<PointerActionItem>), > } > > impl Parameters for ActionsType { > fn from_json(body: &Json) -> WebDriverResult<ActionsType> { > // These unwraps are OK as long as this is only called from ActionSequence::from_json > let data = body.as_object().expect("Body should be a JSON Object"); >- let actions_type = body.find("type").and_then(|x| x.as_string()).expect("Type should be a string"); >- let actions_chain = try_opt!(try_opt!(data.get("actions"), >- ErrorStatus::InvalidArgument, >- "Missing actions parameter").as_array(), >- ErrorStatus::InvalidArgument, >- "Parameter 'actions' was not an array"); >+ let actions_type = body >+ .find("type") >+ .and_then(|x| x.as_string()) >+ .expect("Type should be a string"); >+ let actions_chain = try_opt!( >+ try_opt!( >+ data.get("actions"), >+ ErrorStatus::InvalidArgument, >+ "Missing actions parameter" >+ ).as_array(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'actions' was not an array" >+ ); > match actions_type { > "none" => { > let mut actions = Vec::with_capacity(actions_chain.len()); > for action_body in actions_chain.iter() { > actions.push(try!(NullActionItem::from_json(action_body))); >- }; >+ } > Ok(ActionsType::Null(actions)) >- }, >+ } > "key" => { > let mut actions = Vec::with_capacity(actions_chain.len()); > for action_body in actions_chain.iter() { > actions.push(try!(KeyActionItem::from_json(action_body))); >- }; >+ } > Ok(ActionsType::Key(actions)) >- }, >+ } > "pointer" => { > let mut actions = Vec::with_capacity(actions_chain.len()); > let parameters = match data.get("parameters") { > Some(x) => try!(PointerActionParameters::from_json(x)), >- None => Default::default() >+ None => Default::default(), > }; > > for action_body in actions_chain.iter() { > actions.push(try!(PointerActionItem::from_json(action_body))); > } > Ok(ActionsType::Pointer(parameters, actions)) > } >- _ => panic!("Got unexpected action type after checking type") >+ _ => panic!("Got unexpected action type after checking type"), > } > } > } > > #[derive(Debug, PartialEq)] > pub enum PointerType { > Mouse, > Pen, >@@ -131,22 +153,22 @@ pub enum PointerType { > impl Parameters for PointerType { > fn from_json(body: &Json) -> WebDriverResult<PointerType> { > match body.as_string() { > Some("mouse") => Ok(PointerType::Mouse), > Some("pen") => Ok(PointerType::Pen), > Some("touch") => Ok(PointerType::Touch), > Some(_) => Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Unsupported pointer type" >+ "Unsupported pointer type", > )), > None => Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Pointer type was not a string" >- )) >+ "Pointer type was not a string", >+ )), > } > } > } > > impl ToJson for PointerType { > fn to_json(&self) -> Json { > match *self { > PointerType::Mouse => "mouse".to_json(), >@@ -159,208 +181,235 @@ impl ToJson for PointerType { > impl Default for PointerType { > fn default() -> PointerType { > PointerType::Mouse > } > } > > #[derive(Debug, Default, PartialEq)] > pub struct PointerActionParameters { >- pub pointer_type: PointerType >+ pub pointer_type: PointerType, > } > > impl Parameters for PointerActionParameters { > fn from_json(body: &Json) -> WebDriverResult<PointerActionParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Parameter 'parameters' was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'parameters' was not an object" >+ ); > let pointer_type = match data.get("pointerType") { > Some(x) => try!(PointerType::from_json(x)), >- None => PointerType::default() >+ None => PointerType::default(), > }; > Ok(PointerActionParameters { >- pointer_type: pointer_type >+ pointer_type: pointer_type, > }) > } > } > > impl ToJson for PointerActionParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("pointerType".to_owned(), >- self.pointer_type.to_json()); >+ data.insert("pointerType".to_owned(), self.pointer_type.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub enum NullActionItem { >- General(GeneralAction) >+ General(GeneralAction), > } > > impl Parameters for NullActionItem { > fn from_json(body: &Json) -> WebDriverResult<NullActionItem> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Actions chain was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Actions chain was not an object" >+ ); > let type_name = try_opt!( >- try_opt!(data.get("type"), >- ErrorStatus::InvalidArgument, >- "Missing 'type' parameter").as_string(), >+ try_opt!( >+ data.get("type"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'type' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "Parameter 'type' was not a string"); >+ "Parameter 'type' was not a string" >+ ); > match type_name { >- "pause" => Ok(NullActionItem::General( >- try!(GeneralAction::from_json(body)))), >- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Invalid type attribute")) >+ "pause" => Ok(NullActionItem::General(try!(GeneralAction::from_json( >+ body >+ )))), >+ _ => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Invalid type attribute", >+ )) >+ } > } > } > } > > impl ToJson for NullActionItem { > fn to_json(&self) -> Json { > match self { > &NullActionItem::General(ref x) => x.to_json(), > } > } > } > > #[derive(Debug, PartialEq)] > pub enum KeyActionItem { > General(GeneralAction), >- Key(KeyAction) >+ Key(KeyAction), > } > > impl Parameters for KeyActionItem { > fn from_json(body: &Json) -> WebDriverResult<KeyActionItem> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Key action item was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Key action item was not an object" >+ ); > let type_name = try_opt!( >- try_opt!(data.get("type"), >- ErrorStatus::InvalidArgument, >- "Missing 'type' parameter").as_string(), >+ try_opt!( >+ data.get("type"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'type' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "Parameter 'type' was not a string"); >+ "Parameter 'type' was not a string" >+ ); > match type_name { >- "pause" => Ok(KeyActionItem::General( >- try!(GeneralAction::from_json(body)))), >- _ => Ok(KeyActionItem::Key( >- try!(KeyAction::from_json(body)))) >+ "pause" => Ok(KeyActionItem::General(try!(GeneralAction::from_json(body)))), >+ _ => Ok(KeyActionItem::Key(try!(KeyAction::from_json(body)))), > } > } > } > > impl ToJson for KeyActionItem { > fn to_json(&self) -> Json { > match *self { > KeyActionItem::General(ref x) => x.to_json(), >- KeyActionItem::Key(ref x) => x.to_json() >+ KeyActionItem::Key(ref x) => x.to_json(), > } > } > } > > #[derive(Debug, PartialEq)] > pub enum PointerActionItem { > General(GeneralAction), >- Pointer(PointerAction) >+ Pointer(PointerAction), > } > > impl Parameters for PointerActionItem { > fn from_json(body: &Json) -> WebDriverResult<PointerActionItem> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Pointer action item was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Pointer action item was not an object" >+ ); > let type_name = try_opt!( >- try_opt!(data.get("type"), >- ErrorStatus::InvalidArgument, >- "Missing 'type' parameter").as_string(), >+ try_opt!( >+ data.get("type"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'type' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "Parameter 'type' was not a string"); >+ "Parameter 'type' was not a string" >+ ); > > match type_name { >- "pause" => Ok(PointerActionItem::General(try!(GeneralAction::from_json(body)))), >- _ => Ok(PointerActionItem::Pointer(try!(PointerAction::from_json(body)))) >+ "pause" => Ok(PointerActionItem::General(try!(GeneralAction::from_json( >+ body >+ )))), >+ _ => Ok(PointerActionItem::Pointer(try!(PointerAction::from_json( >+ body >+ )))), > } > } > } > > impl ToJson for PointerActionItem { > fn to_json(&self) -> Json { > match self { > &PointerActionItem::General(ref x) => x.to_json(), >- &PointerActionItem::Pointer(ref x) => x.to_json() >+ &PointerActionItem::Pointer(ref x) => x.to_json(), > } > } > } > > #[derive(Debug, PartialEq)] > pub enum GeneralAction { >- Pause(PauseAction) >+ Pause(PauseAction), > } > > impl Parameters for GeneralAction { > fn from_json(body: &Json) -> WebDriverResult<GeneralAction> { > match body.find("type").and_then(|x| x.as_string()) { > Some("pause") => Ok(GeneralAction::Pause(try!(PauseAction::from_json(body)))), >- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Invalid or missing type attribute")) >+ _ => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Invalid or missing type attribute", >+ )), > } > } > } > > impl ToJson for GeneralAction { > fn to_json(&self) -> Json { > match self { >- &GeneralAction::Pause(ref x) => x.to_json() >+ &GeneralAction::Pause(ref x) => x.to_json(), > } > } > } > > #[derive(Debug, PartialEq)] > pub struct PauseAction { >- pub duration: u64 >+ pub duration: u64, > } > > impl Parameters for PauseAction { > fn from_json(body: &Json) -> WebDriverResult<PauseAction> { > let default = Json::U64(0); > Ok(PauseAction { >- duration: try_opt!(body.find("duration").unwrap_or(&default).as_u64(), >- ErrorStatus::InvalidArgument, >- "Parameter 'duration' was not a positive integer") >+ duration: try_opt!( >+ body.find("duration").unwrap_or(&default).as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'duration' was not a positive integer" >+ ), > }) > } > } > > impl ToJson for PauseAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "pause".to_json()); >- data.insert("duration".to_owned(), >- self.duration.to_json()); >+ data.insert("type".to_owned(), "pause".to_json()); >+ data.insert("duration".to_owned(), self.duration.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub enum KeyAction { > Up(KeyUpAction), >- Down(KeyDownAction) >+ Down(KeyDownAction), > } > > impl Parameters for KeyAction { > fn from_json(body: &Json) -> WebDriverResult<KeyAction> { > match body.find("type").and_then(|x| x.as_string()) { > Some("keyDown") => Ok(KeyAction::Down(try!(KeyDownAction::from_json(body)))), > Some("keyUp") => Ok(KeyAction::Up(try!(KeyUpAction::from_json(body)))), >- Some(_) | None => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Invalid type attribute value for key action")) >+ Some(_) | None => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Invalid type attribute value for key action", >+ )), > } > } > } > > impl ToJson for KeyAction { > fn to_json(&self) -> Json { > match self { > &KeyAction::Down(ref x) => x.to_json(), >@@ -371,110 +420,112 @@ impl ToJson for KeyAction { > > fn validate_key_value(value_str: &str) -> WebDriverResult<String> { > let mut graphemes = value_str.graphemes(true); > let value = if let Some(g) = graphemes.next() { > g > } else { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Parameter 'value' was an empty string")) >+ "Parameter 'value' was an empty string", >+ )); > }; > if graphemes.next().is_some() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Parameter 'value' contained multiple graphemes")) >+ "Parameter 'value' contained multiple graphemes", >+ )); > }; > Ok(value.to_string()) > } > > #[derive(Debug, PartialEq)] > pub struct KeyUpAction { >- pub value: String >+ pub value: String, > } > > impl Parameters for KeyUpAction { > fn from_json(body: &Json) -> WebDriverResult<KeyUpAction> { > let value_str = try_opt!( >- try_opt!(body.find("value"), >- ErrorStatus::InvalidArgument, >- "Missing value parameter").as_string(), >+ try_opt!( >+ body.find("value"), > ErrorStatus::InvalidArgument, >- "Parameter 'value' was not a string"); >+ "Missing value parameter" >+ ).as_string(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'value' was not a string" >+ ); > > let value = try!(validate_key_value(value_str)); >- Ok(KeyUpAction { >- value: value >- }) >+ Ok(KeyUpAction { value: value }) > } > } > > impl ToJson for KeyUpAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "keyUp".to_json()); >- data.insert("value".to_string(), >- self.value.to_string().to_json()); >+ data.insert("type".to_owned(), "keyUp".to_json()); >+ data.insert("value".to_string(), self.value.to_string().to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct KeyDownAction { >- pub value: String >+ pub value: String, > } > > impl Parameters for KeyDownAction { > fn from_json(body: &Json) -> WebDriverResult<KeyDownAction> { > let value_str = try_opt!( >- try_opt!(body.find("value"), >- ErrorStatus::InvalidArgument, >- "Missing value parameter").as_string(), >+ try_opt!( >+ body.find("value"), > ErrorStatus::InvalidArgument, >- "Parameter 'value' was not a string"); >+ "Missing value parameter" >+ ).as_string(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'value' was not a string" >+ ); > let value = try!(validate_key_value(value_str)); >- Ok(KeyDownAction { >- value: value >- }) >+ Ok(KeyDownAction { value: value }) > } > } > > impl ToJson for KeyDownAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "keyDown".to_json()); >- data.insert("value".to_owned(), >- self.value.to_string().to_json()); >+ data.insert("type".to_owned(), "keyDown".to_json()); >+ data.insert("value".to_owned(), self.value.to_string().to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub enum PointerOrigin { > Viewport, > Pointer, > Element(WebElement), > } > > impl Parameters for PointerOrigin { > fn from_json(body: &Json) -> WebDriverResult<PointerOrigin> { > match *body { >- Json::String(ref x) => { >- match &**x { >- "viewport" => Ok(PointerOrigin::Viewport), >- "pointer" => Ok(PointerOrigin::Pointer), >- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Unknown pointer origin")) >- } >+ Json::String(ref x) => match &**x { >+ "viewport" => Ok(PointerOrigin::Viewport), >+ "pointer" => Ok(PointerOrigin::Pointer), >+ _ => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Unknown pointer origin", >+ )), > }, > Json::Object(_) => Ok(PointerOrigin::Element(try!(WebElement::from_json(body)))), >- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Pointer origin was not a string or an object")) >+ _ => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Pointer origin was not a string or an object", >+ )), > } > } > } > > impl ToJson for PointerOrigin { > fn to_json(&self) -> Json { > match *self { > PointerOrigin::Viewport => "viewport".to_json(), >@@ -490,166 +541,170 @@ impl Default for PointerOrigin { > } > } > > #[derive(Debug, PartialEq)] > pub enum PointerAction { > Up(PointerUpAction), > Down(PointerDownAction), > Move(PointerMoveAction), >- Cancel >+ Cancel, > } > > impl Parameters for PointerAction { > fn from_json(body: &Json) -> WebDriverResult<PointerAction> { > match body.find("type").and_then(|x| x.as_string()) { > Some("pointerUp") => Ok(PointerAction::Up(try!(PointerUpAction::from_json(body)))), >- Some("pointerDown") => Ok(PointerAction::Down(try!(PointerDownAction::from_json(body)))), >- Some("pointerMove") => Ok(PointerAction::Move(try!(PointerMoveAction::from_json(body)))), >+ Some("pointerDown") => Ok(PointerAction::Down(try!(PointerDownAction::from_json( >+ body >+ )))), >+ Some("pointerMove") => Ok(PointerAction::Move(try!(PointerMoveAction::from_json( >+ body >+ )))), > Some("pointerCancel") => Ok(PointerAction::Cancel), > Some(_) | None => Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- "Missing or invalid type argument for pointer action")) >+ "Missing or invalid type argument for pointer action", >+ )), > } > } > } > > impl ToJson for PointerAction { > fn to_json(&self) -> Json { > match self { > &PointerAction::Down(ref x) => x.to_json(), > &PointerAction::Up(ref x) => x.to_json(), > &PointerAction::Move(ref x) => x.to_json(), > &PointerAction::Cancel => { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "pointerCancel".to_json()); >+ data.insert("type".to_owned(), "pointerCancel".to_json()); > Json::Object(data) > } > } > } > } > > #[derive(Debug, PartialEq)] > pub struct PointerUpAction { > pub button: u64, > } > > impl Parameters for PointerUpAction { > fn from_json(body: &Json) -> WebDriverResult<PointerUpAction> { > let button = try_opt!( >- try_opt!(body.find("button"), >- ErrorStatus::InvalidArgument, >- "Missing button parameter").as_u64(), >+ try_opt!( >+ body.find("button"), >+ ErrorStatus::InvalidArgument, >+ "Missing button parameter" >+ ).as_u64(), > ErrorStatus::InvalidArgument, >- "Parameter 'button' was not a positive integer"); >+ "Parameter 'button' was not a positive integer" >+ ); > >- Ok(PointerUpAction { >- button: button >- }) >+ Ok(PointerUpAction { button: button }) > } > } > > impl ToJson for PointerUpAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "pointerUp".to_json()); >+ data.insert("type".to_owned(), "pointerUp".to_json()); > data.insert("button".to_owned(), self.button.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct PointerDownAction { > pub button: u64, > } > > impl Parameters for PointerDownAction { > fn from_json(body: &Json) -> WebDriverResult<PointerDownAction> { > let button = try_opt!( >- try_opt!(body.find("button"), >- ErrorStatus::InvalidArgument, >- "Missing button parameter").as_u64(), >+ try_opt!( >+ body.find("button"), >+ ErrorStatus::InvalidArgument, >+ "Missing button parameter" >+ ).as_u64(), > ErrorStatus::InvalidArgument, >- "Parameter 'button' was not a positive integer"); >+ "Parameter 'button' was not a positive integer" >+ ); > >- Ok(PointerDownAction { >- button: button >- }) >+ Ok(PointerDownAction { button: button }) > } > } > > impl ToJson for PointerDownAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("type".to_owned(), >- "pointerDown".to_json()); >+ data.insert("type".to_owned(), "pointerDown".to_json()); > data.insert("button".to_owned(), self.button.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct PointerMoveAction { > pub duration: Nullable<u64>, > pub origin: PointerOrigin, > pub x: Nullable<i64>, >- pub y: Nullable<i64> >+ pub y: Nullable<i64>, > } > > impl Parameters for PointerMoveAction { > fn from_json(body: &Json) -> WebDriverResult<PointerMoveAction> { > let duration = match body.find("duration") { >- Some(duration) => Some(try_opt!(duration.as_u64(), >- ErrorStatus::InvalidArgument, >- "Parameter 'duration' was not a positive integer")), >- None => None >- >+ Some(duration) => Some(try_opt!( >+ duration.as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'duration' was not a positive integer" >+ )), >+ None => None, > }; > > let origin = match body.find("origin") { > Some(o) => try!(PointerOrigin::from_json(o)), >- None => PointerOrigin::default() >+ None => PointerOrigin::default(), > }; > > let x = match body.find("x") { >- Some(x) => { >- Some(try_opt!(x.as_i64(), >- ErrorStatus::InvalidArgument, >- "Parameter 'x' was not an integer")) >- }, >- None => None >+ Some(x) => Some(try_opt!( >+ x.as_i64(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'x' was not an integer" >+ )), >+ None => None, > }; > > let y = match body.find("y") { >- Some(y) => { >- Some(try_opt!(y.as_i64(), >- ErrorStatus::InvalidArgument, >- "Parameter 'y' was not an integer")) >- }, >- None => None >+ Some(y) => Some(try_opt!( >+ y.as_i64(), >+ ErrorStatus::InvalidArgument, >+ "Parameter 'y' was not an integer" >+ )), >+ None => None, > }; > > Ok(PointerMoveAction { > duration: duration.into(), > origin: origin.into(), > x: x.into(), > y: y.into(), > }) > } > } > > impl ToJson for PointerMoveAction { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("type".to_owned(), "pointerMove".to_json()); > if self.duration.is_value() { >- data.insert("duration".to_owned(), >- self.duration.to_json()); >+ data.insert("duration".to_owned(), self.duration.to_json()); > } > > data.insert("origin".to_owned(), self.origin.to_json()); > > if self.x.is_value() { > data.insert("x".to_owned(), self.x.to_json()); > } > if self.y.is_value() { >diff --git a/testing/webdriver/src/capabilities.rs b/testing/webdriver/src/capabilities.rs >index fd10ca690034..fc49c08d4116 100644 >--- a/testing/webdriver/src/capabilities.rs >+++ b/testing/webdriver/src/capabilities.rs >@@ -74,18 +74,20 @@ pub trait BrowserCapabilities { > /// This trait is expected to be implemented on objects holding the capabilities > /// from a new session command. > pub trait CapabilitiesMatching { > /// Match the BrowserCapabilities against some candidate capabilites > /// > /// Takes a BrowserCapabilites object and returns a set of capabilites that > /// are valid for that browser, if any, or None if there are no matching > /// capabilities. >- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T) >- -> WebDriverResult<Option<Capabilities>>; >+ fn match_browser<T: BrowserCapabilities>( >+ &self, >+ browser_capabilities: &mut T, >+ ) -> WebDriverResult<Option<Capabilities>>; > } > > #[derive(Debug, PartialEq)] > pub struct SpecNewSessionParameters { > pub alwaysMatch: Capabilities, > pub firstMatch: Vec<Capabilities>, > } > >@@ -142,142 +144,164 @@ impl SpecNewSessionParameters { > } > } > } > Ok(capabilities) > } > > fn validate_page_load_strategy(value: &Json) -> WebDriverResult<()> { > match value { >- &Json::String(ref x) => { >- match &**x { >- "normal" | >- "eager" | >- "none" => {}, >- x => { >- return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("Invalid page load strategy: {}", x))) >- } >+ &Json::String(ref x) => match &**x { >+ "normal" | "eager" | "none" => {} >+ x => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Invalid page load strategy: {}", x), >+ )) > } >+ }, >+ _ => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "pageLoadStrategy is not a string", >+ )) > } >- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "pageLoadStrategy is not a string")) > } > Ok(()) > } > > fn validate_proxy(proxy_value: &Json) -> WebDriverResult<()> { >- let obj = try_opt!(proxy_value.as_object(), >- ErrorStatus::InvalidArgument, >- "proxy is not an object"); >+ let obj = try_opt!( >+ proxy_value.as_object(), >+ ErrorStatus::InvalidArgument, >+ "proxy is not an object" >+ ); > > for (key, value) in obj.iter() { > match &**key { > "proxyType" => match value.as_string() { >- Some("pac") | >- Some("direct") | >- Some("autodetect") | >- Some("system") | >- Some("manual") => {}, >- Some(x) => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("Invalid proxyType value: {}", x))), >- None => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("proxyType is not a string: {}", value))), >+ Some("pac") | Some("direct") | Some("autodetect") | Some("system") >+ | Some("manual") => {} >+ Some(x) => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Invalid proxyType value: {}", x), >+ )) >+ } >+ None => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("proxyType is not a string: {}", value), >+ )) >+ } > }, > > "proxyAutoconfigUrl" => match value.as_string() { > Some(x) => { > Url::parse(x).or(Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- format!("proxyAutoconfigUrl is not a valid URL: {}", x))))?; >- }, >- None => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- "proxyAutoconfigUrl is not a string" >- )) >+ format!("proxyAutoconfigUrl is not a valid URL: {}", x), >+ )))?; >+ } >+ None => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "proxyAutoconfigUrl is not a string", >+ )) >+ } > }, > > "ftpProxy" => SpecNewSessionParameters::validate_host(value, "ftpProxy")?, > "httpProxy" => SpecNewSessionParameters::validate_host(value, "httpProxy")?, > "noProxy" => SpecNewSessionParameters::validate_no_proxy(value)?, > "sslProxy" => SpecNewSessionParameters::validate_host(value, "sslProxy")?, > "socksProxy" => SpecNewSessionParameters::validate_host(value, "socksProxy")?, > "socksVersion" => if !value.is_number() { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- format!("socksVersion is not a number: {}", value) >- )) >+ format!("socksVersion is not a number: {}", value), >+ )); > }, > >- x => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("Invalid proxy configuration entry: {}", x))) >+ x => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Invalid proxy configuration entry: {}", x), >+ )) >+ } > } > } > > Ok(()) > } > > fn validate_no_proxy(value: &Json) -> WebDriverResult<()> { > match value.as_array() { > Some(hosts) => { > for host in hosts { > match host.as_string() { >- Some(_) => {}, >- None => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("noProxy item is not a string: {}", host) >- )) >+ Some(_) => {} >+ None => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("noProxy item is not a string: {}", host), >+ )) >+ } > } > } >- }, >- None => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("noProxy is not an array: {}", value) >- )) >+ } >+ None => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("noProxy is not an array: {}", value), >+ )) >+ } > } > > Ok(()) > } > > /// Validate whether a named capability is JSON value is a string containing a host > /// and possible port > fn validate_host(value: &Json, entry: &str) -> WebDriverResult<()> { > match value.as_string() { > Some(host) => { > if host.contains("://") { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- format!("{} must not contain a scheme: {}", entry, host))); >+ format!("{} must not contain a scheme: {}", entry, host), >+ )); > } > > // Temporarily add a scheme so the host can be parsed as URL > let s = String::from(format!("http://{}", host)); > let url = Url::parse(s.as_str()).or(Err(WebDriverError::new( > ErrorStatus::InvalidArgument, >- format!("{} is not a valid URL: {}", entry, host))))?; >+ format!("{} is not a valid URL: {}", entry, host), >+ )))?; > >- if url.username() != "" || >- url.password() != None || >- url.path() != "/" || >- url.query() != None || >- url.fragment() != None { >- return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("{} is not of the form host[:port]: {}", entry, host))); >- } >- }, >+ if url.username() != "" >+ || url.password() != None >+ || url.path() != "/" >+ || url.query() != None >+ || url.fragment() != None >+ { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("{} is not of the form host[:port]: {}", entry, host), >+ )); >+ } >+ } > >- None => return Err(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- format!("{} is not a string: {}", entry, value) >- )) >+ None => { >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("{} is not a string: {}", entry, value), >+ )) >+ } > } > > Ok(()) > } > > fn validate_timeouts(value: &Json) -> WebDriverResult<()> { > let obj = try_opt!( > value.as_object(), >@@ -316,21 +340,17 @@ impl SpecNewSessionParameters { > fn validate_unhandled_prompt_behaviour(value: &Json) -> WebDriverResult<()> { > let behaviour = try_opt!( > value.as_string(), > ErrorStatus::InvalidArgument, > format!("unhandledPromptBehavior is not a string: {}", value) > ); > > match behaviour { >- "accept" | >- "accept and notify" | >- "dismiss" | >- "dismiss and notify" | >- "ignore" => {}, >+ "accept" | "accept and notify" | "dismiss" | "dismiss and notify" | "ignore" => {} > x => { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, > format!("Invalid unhandledPromptBehavior value: {}", x), > )) > } > } > >@@ -338,17 +358,20 @@ impl SpecNewSessionParameters { > } > } > > impl Parameters for SpecNewSessionParameters { > fn from_json(body: &Json) -> WebDriverResult<SpecNewSessionParameters> { > let data = try_opt!( > body.as_object(), > ErrorStatus::UnknownError, >- format!("Malformed capabilities, message body is not an object: {}", body) >+ format!( >+ "Malformed capabilities, message body is not an object: {}", >+ body >+ ) > ); > > let capabilities = try_opt!( > try_opt!( > data.get("capabilities"), > ErrorStatus::InvalidArgument, > "Malformed capabilities, missing \"capabilities\" field" > ).as_object(), >@@ -369,23 +392,22 @@ impl Parameters for SpecNewSessionParameters { > let first_matches = try_opt!( > capabilities > .get("firstMatch") > .unwrap_or(&default_first_matches) > .as_array(), > ErrorStatus::InvalidArgument, > "Malformed capabilities, firstMatch field is not an array" > ).iter() >- .map(|x| { >- x.as_object().map(|x| x.clone()).ok_or(WebDriverError::new( >- ErrorStatus::InvalidArgument, >- "Malformed capabilities, firstMatch entry is not an object", >- )) >- }) >- .collect::<WebDriverResult<Vec<Capabilities>>>()?; >+ .map(|x| { >+ x.as_object().map(|x| x.clone()).ok_or(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Malformed capabilities, firstMatch entry is not an object", >+ )) >+ }).collect::<WebDriverResult<Vec<Capabilities>>>()?; > > return Ok(SpecNewSessionParameters { > alwaysMatch: always_match.clone(), > firstMatch: first_matches, > }); > } > } > >@@ -410,29 +432,29 @@ impl CapabilitiesMatching for SpecNewSessionParameters { > &self.firstMatch > } else { > &default > }; > > let merged_capabilities = capabilities_list > .iter() > .map(|first_match_entry| { >- if first_match_entry.keys().any(|k| self.alwaysMatch.contains_key(k)) { >+ if first_match_entry >+ .keys() >+ .any(|k| self.alwaysMatch.contains_key(k)) >+ { > return Err(WebDriverError::new( > ErrorStatus::InvalidArgument, > "firstMatch key shadowed a value in alwaysMatch", > )); > } > let mut merged = self.alwaysMatch.clone(); > merged.append(&mut first_match_entry.clone()); > Ok(merged) >- }) >- .map(|merged| { >- merged.and_then(|x| self.validate(x, browser_capabilities)) >- }) >+ }).map(|merged| merged.and_then(|x| self.validate(x, browser_capabilities))) > .collect::<WebDriverResult<Vec<Capabilities>>>()?; > > let selected = merged_capabilities > .iter() > .filter_map(|merged| { > browser_capabilities.init(merged); > > for (key, value) in merged.iter() { >@@ -470,29 +492,27 @@ impl CapabilitiesMatching for SpecNewSessionParameters { > .platform_name(merged) > .ok() > .and_then(|x| x); > if value.as_string() != browserValue.as_ref().map(|x| &**x) { > return None; > } > } > "acceptInsecureCerts" => { >- if value.as_boolean().unwrap_or(false) && >- !browser_capabilities >- .accept_insecure_certs(merged) >- .unwrap_or(false) >+ if value.as_boolean().unwrap_or(false) && !browser_capabilities >+ .accept_insecure_certs(merged) >+ .unwrap_or(false) > { > return None; > } > } > "setWindowRect" => { >- if value.as_boolean().unwrap_or(false) && >- !browser_capabilities >- .set_window_rect(merged) >- .unwrap_or(false) >+ if value.as_boolean().unwrap_or(false) && !browser_capabilities >+ .set_window_rect(merged) >+ .unwrap_or(false) > { > return None; > } > } > "proxy" => { > let default = BTreeMap::new(); > let proxy = value.as_object().unwrap_or(&default); > if !browser_capabilities >@@ -513,18 +533,17 @@ impl CapabilitiesMatching for SpecNewSessionParameters { > } else { > // Accept the capability > } > } > } > } > > return Some(merged); >- }) >- .next() >+ }).next() > .map(|x| x.clone()); > Ok(selected) > } > } > > #[derive(Debug, PartialEq)] > pub struct LegacyNewSessionParameters { > pub desired: Capabilities, >@@ -554,17 +573,20 @@ impl CapabilitiesMatching for LegacyNewSessionParameters { > } > } > > impl Parameters for LegacyNewSessionParameters { > fn from_json(body: &Json) -> WebDriverResult<LegacyNewSessionParameters> { > let data = try_opt!( > body.as_object(), > ErrorStatus::UnknownError, >- format!("Malformed legacy capabilities, message body is not an object: {}", body) >+ format!( >+ "Malformed legacy capabilities, message body is not an object: {}", >+ body >+ ) > ); > > let desired = if let Some(capabilities) = data.get("desiredCapabilities") { > try_opt!( > capabilities.as_object(), > ErrorStatus::InvalidArgument, > "Malformed legacy capabilities, desiredCapabilities field is not an object" > ).clone() >@@ -592,18 +614,18 @@ impl ToJson for LegacyNewSessionParameters { > data.insert("desiredCapabilities".to_owned(), self.desired.to_json()); > data.insert("requiredCapabilities".to_owned(), self.required.to_json()); > Json::Object(data) > } > } > > #[cfg(test)] > mod tests { >- use rustc_serialize::json::Json; > use super::{SpecNewSessionParameters, WebDriverResult}; >+ use rustc_serialize::json::Json; > > fn validate_proxy(value: &str) -> WebDriverResult<()> { > let data = Json::from_str(value).unwrap(); > SpecNewSessionParameters::validate_proxy(&data) > } > > #[test] > fn test_validate_proxy() { >diff --git a/testing/webdriver/src/command.rs b/testing/webdriver/src/command.rs >index 37cd841e79b5..25cc0ed5bd5e 100644 >--- a/testing/webdriver/src/command.rs >+++ b/testing/webdriver/src/command.rs >@@ -1,17 +1,19 @@ >-use actions::{ActionSequence}; >-use capabilities::{SpecNewSessionParameters, LegacyNewSessionParameters, >- CapabilitiesMatching, BrowserCapabilities, Capabilities}; >-use common::{Date, Nullable, WebElement, FrameId, LocatorStrategy}; >-use error::{WebDriverResult, WebDriverError, ErrorStatus}; >-use httpapi::{Route, WebDriverExtensionRoute, VoidWebDriverExtensionRoute}; >+use actions::ActionSequence; >+use capabilities::{ >+ BrowserCapabilities, Capabilities, CapabilitiesMatching, LegacyNewSessionParameters, >+ SpecNewSessionParameters, >+}; >+use common::{Date, FrameId, LocatorStrategy, Nullable, WebElement}; >+use error::{ErrorStatus, WebDriverError, WebDriverResult}; >+use httpapi::{Route, VoidWebDriverExtensionRoute, WebDriverExtensionRoute}; > use regex::Captures; > use rustc_serialize::json; >-use rustc_serialize::json::{ToJson, Json}; >+use rustc_serialize::json::{Json, ToJson}; > use std::collections::BTreeMap; > > #[derive(Debug, PartialEq)] > pub enum WebDriverCommand<T: WebDriverExtensionCommand> { > NewSession(NewSessionParameters), > DeleteSession, > Get(GetParameters), > GetCurrentUrl, >@@ -62,368 +64,406 @@ pub enum WebDriverCommand<T: WebDriverExtensionCommand> { > ReleaseActions, > DismissAlert, > AcceptAlert, > GetAlertText, > SendAlertText(SendKeysParameters), > TakeScreenshot, > TakeElementScreenshot(WebElement), > Status, >- Extension(T) >+ Extension(T), > } > >-pub trait WebDriverExtensionCommand : Clone + Send + PartialEq { >+pub trait WebDriverExtensionCommand: Clone + Send + PartialEq { > fn parameters_json(&self) -> Option<Json>; > } > > #[derive(Clone, Debug, PartialEq)] > pub struct VoidWebDriverExtensionCommand; > > impl WebDriverExtensionCommand for VoidWebDriverExtensionCommand { > fn parameters_json(&self) -> Option<Json> { > panic!("No extensions implemented"); > } > } > > #[derive(Debug, PartialEq)] >-pub struct WebDriverMessage <U: WebDriverExtensionRoute=VoidWebDriverExtensionRoute> { >+pub struct WebDriverMessage<U: WebDriverExtensionRoute = VoidWebDriverExtensionRoute> { > pub session_id: Option<String>, > pub command: WebDriverCommand<U::Command>, > } > > impl<U: WebDriverExtensionRoute> WebDriverMessage<U> { >- pub fn new(session_id: Option<String>, >- command: WebDriverCommand<U::Command>) >- -> WebDriverMessage<U> { >+ pub fn new( >+ session_id: Option<String>, >+ command: WebDriverCommand<U::Command>, >+ ) -> WebDriverMessage<U> { > WebDriverMessage { > session_id: session_id, > command: command, > } > } > >- pub fn from_http(match_type: Route<U>, >- params: &Captures, >- raw_body: &str, >- requires_body: bool) >- -> WebDriverResult<WebDriverMessage<U>> { >+ pub fn from_http( >+ match_type: Route<U>, >+ params: &Captures, >+ raw_body: &str, >+ requires_body: bool, >+ ) -> WebDriverResult<WebDriverMessage<U>> { > let session_id = WebDriverMessage::<U>::get_session_id(params); > let body_data = try!(WebDriverMessage::<U>::decode_body(raw_body, requires_body)); > > let command = match match_type { > Route::NewSession => { > let parameters: NewSessionParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::NewSession(parameters) >- }, >+ } > Route::DeleteSession => WebDriverCommand::DeleteSession, > Route::Get => { > let parameters: GetParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::Get(parameters) >- }, >+ } > Route::GetCurrentUrl => WebDriverCommand::GetCurrentUrl, > Route::GoBack => WebDriverCommand::GoBack, > Route::GoForward => WebDriverCommand::GoForward, > Route::Refresh => WebDriverCommand::Refresh, > Route::GetTitle => WebDriverCommand::GetTitle, > Route::GetPageSource => WebDriverCommand::GetPageSource, > Route::GetWindowHandle => WebDriverCommand::GetWindowHandle, > Route::GetWindowHandles => WebDriverCommand::GetWindowHandles, > Route::CloseWindow => WebDriverCommand::CloseWindow, > Route::GetTimeouts => WebDriverCommand::GetTimeouts, > Route::SetTimeouts => { > let parameters: TimeoutsParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::SetTimeouts(parameters) >- }, >- Route::GetWindowRect | Route::GetWindowPosition | Route::GetWindowSize => WebDriverCommand::GetWindowRect, >+ } >+ Route::GetWindowRect | Route::GetWindowPosition | Route::GetWindowSize => { >+ WebDriverCommand::GetWindowRect >+ } > Route::SetWindowRect | Route::SetWindowPosition | Route::SetWindowSize => { > let parameters: WindowRectParameters = Parameters::from_json(&body_data)?; > WebDriverCommand::SetWindowRect(parameters) >- }, >+ } > Route::MinimizeWindow => WebDriverCommand::MinimizeWindow, > Route::MaximizeWindow => WebDriverCommand::MaximizeWindow, > Route::FullscreenWindow => WebDriverCommand::FullscreenWindow, > Route::SwitchToWindow => { > let parameters: SwitchToWindowParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::SwitchToWindow(parameters) > } > Route::SwitchToFrame => { > let parameters: SwitchToFrameParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::SwitchToFrame(parameters) >- }, >+ } > Route::SwitchToParentFrame => WebDriverCommand::SwitchToParentFrame, > Route::FindElement => { > let parameters: LocatorParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::FindElement(parameters) >- }, >+ } > Route::FindElements => { > let parameters: LocatorParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::FindElements(parameters) >- }, >+ } > Route::FindElementElement => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > let parameters: LocatorParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::FindElementElement(element, parameters) >- }, >+ } > Route::FindElementElements => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > let parameters: LocatorParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::FindElementElements(element, parameters) >- }, >+ } > Route::GetActiveElement => WebDriverCommand::GetActiveElement, > Route::IsDisplayed => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::IsDisplayed(element) >- }, >+ } > Route::IsSelected => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::IsSelected(element) >- }, >+ } > Route::GetElementAttribute => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); >- let attr = try_opt!(params.name("name"), >- ErrorStatus::InvalidArgument, >- "Missing name parameter").as_str(); >+ let attr = try_opt!( >+ params.name("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing name parameter" >+ ).as_str(); > WebDriverCommand::GetElementAttribute(element, attr.into()) >- }, >+ } > Route::GetElementProperty => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); >- let property = try_opt!(params.name("name"), >- ErrorStatus::InvalidArgument, >- "Missing name parameter").as_str(); >+ let property = try_opt!( >+ params.name("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing name parameter" >+ ).as_str(); > WebDriverCommand::GetElementProperty(element, property.into()) >- }, >+ } > Route::GetCSSValue => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); >- let property = try_opt!(params.name("propertyName"), >- ErrorStatus::InvalidArgument, >- "Missing propertyName parameter").as_str(); >+ let property = try_opt!( >+ params.name("propertyName"), >+ ErrorStatus::InvalidArgument, >+ "Missing propertyName parameter" >+ ).as_str(); > WebDriverCommand::GetCSSValue(element, property.into()) >- }, >+ } > Route::GetElementText => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::GetElementText(element) >- }, >+ } > Route::GetElementTagName => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::GetElementTagName(element) >- }, >+ } > Route::GetElementRect => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::GetElementRect(element) >- }, >+ } > Route::IsEnabled => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::IsEnabled(element) >- }, >+ } > Route::ElementClick => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::ElementClick(element) >- }, >+ } > Route::ElementTap => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::ElementTap(element) >- }, >+ } > Route::ElementClear => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::ElementClear(element) >- }, >+ } > Route::ElementSendKeys => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > let parameters: SendKeysParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::ElementSendKeys(element, parameters) >- }, >+ } > Route::ExecuteScript => { >- let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data)); >+ let parameters: JavascriptCommandParameters = >+ try!(Parameters::from_json(&body_data)); > WebDriverCommand::ExecuteScript(parameters) >- }, >+ } > Route::ExecuteAsyncScript => { >- let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data)); >+ let parameters: JavascriptCommandParameters = >+ try!(Parameters::from_json(&body_data)); > WebDriverCommand::ExecuteAsyncScript(parameters) >- }, >- Route::GetCookies => { >- WebDriverCommand::GetCookies >- }, >+ } >+ Route::GetCookies => WebDriverCommand::GetCookies, > Route::GetNamedCookie => { >- let name = try_opt!(params.name("name"), >- ErrorStatus::InvalidArgument, >- "Missing 'name' parameter").as_str().into(); >+ let name = try_opt!( >+ params.name("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'name' parameter" >+ ).as_str() >+ .into(); > WebDriverCommand::GetNamedCookie(name) >- }, >+ } > Route::AddCookie => { > let parameters: AddCookieParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::AddCookie(parameters) >- }, >- Route::DeleteCookies => { >- WebDriverCommand::DeleteCookies >- }, >+ } >+ Route::DeleteCookies => WebDriverCommand::DeleteCookies, > Route::DeleteCookie => { >- let name = try_opt!(params.name("name"), >- ErrorStatus::InvalidArgument, >- "Missing name parameter").as_str().into(); >+ let name = try_opt!( >+ params.name("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing name parameter" >+ ).as_str() >+ .into(); > WebDriverCommand::DeleteCookie(name) >- }, >+ } > Route::PerformActions => { > let parameters: ActionsParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::PerformActions(parameters) >- }, >- Route::ReleaseActions => { >- WebDriverCommand::ReleaseActions >- }, >- Route::DismissAlert => { >- WebDriverCommand::DismissAlert >- }, >- Route::AcceptAlert => { >- WebDriverCommand::AcceptAlert >- }, >- Route::GetAlertText => { >- WebDriverCommand::GetAlertText >- }, >+ } >+ Route::ReleaseActions => WebDriverCommand::ReleaseActions, >+ Route::DismissAlert => WebDriverCommand::DismissAlert, >+ Route::AcceptAlert => WebDriverCommand::AcceptAlert, >+ Route::GetAlertText => WebDriverCommand::GetAlertText, > Route::SendAlertText => { > let parameters: SendKeysParameters = try!(Parameters::from_json(&body_data)); > WebDriverCommand::SendAlertText(parameters) >- }, >+ } > Route::TakeScreenshot => WebDriverCommand::TakeScreenshot, >- Route::TakeElementScreenshot => { >- let element_id = try_opt!(params.name("elementId"), >- ErrorStatus::InvalidArgument, >- "Missing elementId parameter"); >+ Route::TakeElementScreenshot => { >+ let element_id = try_opt!( >+ params.name("elementId"), >+ ErrorStatus::InvalidArgument, >+ "Missing elementId parameter" >+ ); > let element = WebElement::new(element_id.as_str().into()); > WebDriverCommand::TakeElementScreenshot(element) >- }, >+ } > Route::Status => WebDriverCommand::Status, >- Route::Extension(ref extension) => { >- try!(extension.command(params, &body_data)) >- } >+ Route::Extension(ref extension) => try!(extension.command(params, &body_data)), > }; > Ok(WebDriverMessage::new(session_id, command)) > } > > fn get_session_id(params: &Captures) -> Option<String> { > params.name("sessionId").map(|x| x.as_str().into()) > } > > fn decode_body(body: &str, requires_body: bool) -> WebDriverResult<Json> { > if requires_body { > match Json::from_str(body) { > Ok(x @ Json::Object(_)) => Ok(x), >- Ok(_) => { >- Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Body was not a JSON Object")) >- } >+ Ok(_) => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Body was not a JSON Object", >+ )), > Err(json::ParserError::SyntaxError(_, line, col)) => { > let msg = format!("Failed to decode request as JSON: \"{}\"", body); > let stack = format!("Syntax error at :{}:{}", line, col); >- Err(WebDriverError::new_with_stack(ErrorStatus::InvalidArgument, msg, stack)) >- } >- Err(json::ParserError::IoError(e)) => { >- Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- format!("I/O error whilst decoding body: {}", e))) >+ Err(WebDriverError::new_with_stack( >+ ErrorStatus::InvalidArgument, >+ msg, >+ stack, >+ )) > } >+ Err(json::ParserError::IoError(e)) => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("I/O error whilst decoding body: {}", e), >+ )), > } > } else { > Ok(Json::Null) > } > } > } > >-impl <U:WebDriverExtensionRoute> ToJson for WebDriverMessage<U> { >+impl<U: WebDriverExtensionRoute> ToJson for WebDriverMessage<U> { > fn to_json(&self) -> Json { > let parameters = match self.command { >- WebDriverCommand::AcceptAlert | >- WebDriverCommand::CloseWindow | >- WebDriverCommand::ReleaseActions | >- WebDriverCommand::DeleteCookie(_) | >- WebDriverCommand::DeleteCookies | >- WebDriverCommand::DeleteSession | >- WebDriverCommand::DismissAlert | >- WebDriverCommand::ElementClear(_) | >- WebDriverCommand::ElementClick(_) | >- WebDriverCommand::ElementTap(_) | >- WebDriverCommand::GetActiveElement | >- WebDriverCommand::GetAlertText | >- WebDriverCommand::GetNamedCookie(_) | >- WebDriverCommand::GetCookies | >- WebDriverCommand::GetCSSValue(_, _) | >- WebDriverCommand::GetCurrentUrl | >- WebDriverCommand::GetElementAttribute(_, _) | >- WebDriverCommand::GetElementProperty(_, _) | >- WebDriverCommand::GetElementRect(_) | >- WebDriverCommand::GetElementTagName(_) | >- WebDriverCommand::GetElementText(_) | >- WebDriverCommand::GetPageSource | >- WebDriverCommand::GetTimeouts | >- WebDriverCommand::GetTitle | >- WebDriverCommand::GetWindowHandle | >- WebDriverCommand::GetWindowHandles | >- WebDriverCommand::GetWindowRect | >- WebDriverCommand::GoBack | >- WebDriverCommand::GoForward | >- WebDriverCommand::IsDisplayed(_) | >- WebDriverCommand::IsEnabled(_) | >- WebDriverCommand::IsSelected(_) | >- WebDriverCommand::MinimizeWindow | >- WebDriverCommand::MaximizeWindow | >- WebDriverCommand::FullscreenWindow | >- WebDriverCommand::NewSession(_) | >- WebDriverCommand::Refresh | >- WebDriverCommand::Status | >- WebDriverCommand::SwitchToParentFrame | >- WebDriverCommand::TakeElementScreenshot(_) | >- WebDriverCommand::TakeScreenshot => { >- None >- }, >+ WebDriverCommand::AcceptAlert >+ | WebDriverCommand::CloseWindow >+ | WebDriverCommand::ReleaseActions >+ | WebDriverCommand::DeleteCookie(_) >+ | WebDriverCommand::DeleteCookies >+ | WebDriverCommand::DeleteSession >+ | WebDriverCommand::DismissAlert >+ | WebDriverCommand::ElementClear(_) >+ | WebDriverCommand::ElementClick(_) >+ | WebDriverCommand::ElementTap(_) >+ | WebDriverCommand::GetActiveElement >+ | WebDriverCommand::GetAlertText >+ | WebDriverCommand::GetNamedCookie(_) >+ | WebDriverCommand::GetCookies >+ | WebDriverCommand::GetCSSValue(_, _) >+ | WebDriverCommand::GetCurrentUrl >+ | WebDriverCommand::GetElementAttribute(_, _) >+ | WebDriverCommand::GetElementProperty(_, _) >+ | WebDriverCommand::GetElementRect(_) >+ | WebDriverCommand::GetElementTagName(_) >+ | WebDriverCommand::GetElementText(_) >+ | WebDriverCommand::GetPageSource >+ | WebDriverCommand::GetTimeouts >+ | WebDriverCommand::GetTitle >+ | WebDriverCommand::GetWindowHandle >+ | WebDriverCommand::GetWindowHandles >+ | WebDriverCommand::GetWindowRect >+ | WebDriverCommand::GoBack >+ | WebDriverCommand::GoForward >+ | WebDriverCommand::IsDisplayed(_) >+ | WebDriverCommand::IsEnabled(_) >+ | WebDriverCommand::IsSelected(_) >+ | WebDriverCommand::MinimizeWindow >+ | WebDriverCommand::MaximizeWindow >+ | WebDriverCommand::FullscreenWindow >+ | WebDriverCommand::NewSession(_) >+ | WebDriverCommand::Refresh >+ | WebDriverCommand::Status >+ | WebDriverCommand::SwitchToParentFrame >+ | WebDriverCommand::TakeElementScreenshot(_) >+ | WebDriverCommand::TakeScreenshot => None, > > WebDriverCommand::AddCookie(ref x) => Some(x.to_json()), > WebDriverCommand::ElementSendKeys(_, ref x) => Some(x.to_json()), >- WebDriverCommand::ExecuteAsyncScript(ref x) | >- WebDriverCommand::ExecuteScript(ref x) => Some(x.to_json()), >+ WebDriverCommand::ExecuteAsyncScript(ref x) >+ | WebDriverCommand::ExecuteScript(ref x) => Some(x.to_json()), > WebDriverCommand::FindElementElement(_, ref x) => Some(x.to_json()), > WebDriverCommand::FindElementElements(_, ref x) => Some(x.to_json()), > WebDriverCommand::FindElement(ref x) => Some(x.to_json()), > WebDriverCommand::FindElements(ref x) => Some(x.to_json()), > WebDriverCommand::Get(ref x) => Some(x.to_json()), > WebDriverCommand::PerformActions(ref x) => Some(x.to_json()), > WebDriverCommand::SendAlertText(ref x) => Some(x.to_json()), > WebDriverCommand::SetTimeouts(ref x) => Some(x.to_json()), >@@ -454,64 +494,77 @@ pub trait Parameters: Sized { > #[derive(Debug, PartialEq)] > pub enum NewSessionParameters { > Spec(SpecNewSessionParameters), > Legacy(LegacyNewSessionParameters), > } > > impl Parameters for NewSessionParameters { > fn from_json(body: &Json) -> WebDriverResult<NewSessionParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::UnknownError, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); > if data.get("capabilities").is_some() { >- Ok(NewSessionParameters::Spec(try!(SpecNewSessionParameters::from_json(body)))) >+ Ok(NewSessionParameters::Spec(try!( >+ SpecNewSessionParameters::from_json(body) >+ ))) > } else { >- Ok(NewSessionParameters::Legacy(try!(LegacyNewSessionParameters::from_json(body)))) >+ Ok(NewSessionParameters::Legacy(try!( >+ LegacyNewSessionParameters::from_json(body) >+ ))) > } > } > } > > impl ToJson for NewSessionParameters { > fn to_json(&self) -> Json { > match self { > &NewSessionParameters::Spec(ref x) => x.to_json(), >- &NewSessionParameters::Legacy(ref x) => x.to_json() >+ &NewSessionParameters::Legacy(ref x) => x.to_json(), > } > } > } > > impl CapabilitiesMatching for NewSessionParameters { >- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T) >- -> WebDriverResult<Option<Capabilities>> { >+ fn match_browser<T: BrowserCapabilities>( >+ &self, >+ browser_capabilities: &mut T, >+ ) -> WebDriverResult<Option<Capabilities>> { > match self { > &NewSessionParameters::Spec(ref x) => x.match_browser(browser_capabilities), >- &NewSessionParameters::Legacy(ref x) => x.match_browser(browser_capabilities) >+ &NewSessionParameters::Legacy(ref x) => x.match_browser(browser_capabilities), > } > } > } > >- > #[derive(Debug, PartialEq)] > pub struct GetParameters { >- pub url: String >+ pub url: String, > } > > impl Parameters for GetParameters { > fn from_json(body: &Json) -> WebDriverResult<GetParameters> { >- let data = try_opt!(body.as_object(), ErrorStatus::UnknownError, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); > let url = try_opt!( >- try_opt!(data.get("url"), >- ErrorStatus::InvalidArgument, >- "Missing 'url' parameter").as_string(), >+ try_opt!( >+ data.get("url"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'url' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "'url' not a string"); >+ "'url' not a string" >+ ); > Ok(GetParameters { >- url: url.to_string() >+ url: url.to_string(), > }) > } > } > > impl ToJson for GetParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("url".to_string(), self.url.to_json()); >@@ -523,44 +576,46 @@ impl ToJson for GetParameters { > pub struct TimeoutsParameters { > pub script: Option<u64>, > pub page_load: Option<u64>, > pub implicit: Option<u64>, > } > > impl Parameters for TimeoutsParameters { > fn from_json(body: &Json) -> WebDriverResult<TimeoutsParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::UnknownError, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); > > let script = match data.get("script") { >- Some(json) => { >- Some(try_opt!(json.as_u64(), >- ErrorStatus::InvalidArgument, >- "Script timeout duration was not a signed integer")) >- } >+ Some(json) => Some(try_opt!( >+ json.as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Script timeout duration was not a signed integer" >+ )), > None => None, > }; > > let page_load = match data.get("pageLoad") { >- Some(json) => { >- Some(try_opt!(json.as_u64(), >- ErrorStatus::InvalidArgument, >- "Page load timeout duration was not a signed integer")) >- } >+ Some(json) => Some(try_opt!( >+ json.as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Page load timeout duration was not a signed integer" >+ )), > None => None, > }; > > let implicit = match data.get("implicit") { >- Some(json) => { >- Some(try_opt!(json.as_u64(), >- ErrorStatus::InvalidArgument, >- "Implicit timeout duration was not a signed integer")) >- } >+ Some(json) => Some(try_opt!( >+ json.as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Implicit timeout duration was not a signed integer" >+ )), > None => None, > }; > > Ok(TimeoutsParameters { > script: script, > page_load: page_load, > implicit: implicit, > }) >@@ -598,18 +653,21 @@ pub struct WindowRectParameters { > pub x: Nullable<i32>, > pub y: Nullable<i32>, > pub width: Nullable<i32>, > pub height: Nullable<i32>, > } > > impl Parameters for WindowRectParameters { > fn from_json(body: &Json) -> WebDriverResult<WindowRectParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); > > let x = match data.get("x") { > Some(json) => try!(Nullable::from_json(json, |n| { > let x = try_opt!( > n.as_f64(), > ErrorStatus::InvalidArgument, > "'x' is not a number" > ) as i64; >@@ -673,191 +731,220 @@ impl Parameters for WindowRectParameters { > "'height' is larger than i32", > )); > } > Ok(height as i32) > })), > None => Nullable::Null, > }; > >- Ok(WindowRectParameters { x, y, width, height }) >+ Ok(WindowRectParameters { >+ x, >+ y, >+ width, >+ height, >+ }) > } > } > > impl ToJson for WindowRectParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("x".to_string(), self.x.to_json()); > data.insert("y".to_string(), self.y.to_json()); > data.insert("width".to_string(), self.width.to_json()); > data.insert("height".to_string(), self.height.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct SwitchToWindowParameters { >- pub handle: String >+ pub handle: String, > } > > impl Parameters for SwitchToWindowParameters { > fn from_json(body: &Json) -> WebDriverResult<SwitchToWindowParameters> { >- let data = try_opt!(body.as_object(), ErrorStatus::UnknownError, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); > let handle = try_opt!( >- try_opt!(data.get("handle"), >- ErrorStatus::InvalidArgument, >- "Missing 'handle' parameter").as_string(), >+ try_opt!( >+ data.get("handle"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'handle' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "'handle' not a string"); >+ "'handle' not a string" >+ ); > return Ok(SwitchToWindowParameters { >- handle: handle.to_string() >- }) >+ handle: handle.to_string(), >+ }); > } > } > > impl ToJson for SwitchToWindowParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("handle".to_string(), self.handle.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct LocatorParameters { > pub using: LocatorStrategy, >- pub value: String >+ pub value: String, > } > > impl Parameters for LocatorParameters { > fn from_json(body: &Json) -> WebDriverResult<LocatorParameters> { >- let data = try_opt!(body.as_object(), ErrorStatus::UnknownError, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); > >- let using = try!(LocatorStrategy::from_json( >- try_opt!(data.get("using"), >- ErrorStatus::InvalidArgument, >- "Missing 'using' parameter"))); >+ let using = try!(LocatorStrategy::from_json(try_opt!( >+ data.get("using"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'using' parameter" >+ ))); > > let value = try_opt!( >- try_opt!(data.get("value"), >- ErrorStatus::InvalidArgument, >- "Missing 'value' parameter").as_string(), >+ try_opt!( >+ data.get("value"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'value' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "Could not convert using to string").to_string(); >+ "Could not convert using to string" >+ ).to_string(); > > return Ok(LocatorParameters { > using: using, >- value: value >- }) >+ value: value, >+ }); > } > } > > impl ToJson for LocatorParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("using".to_string(), self.using.to_json()); > data.insert("value".to_string(), self.value.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct SwitchToFrameParameters { >- pub id: FrameId >+ pub id: FrameId, > } > > impl Parameters for SwitchToFrameParameters { > fn from_json(body: &Json) -> WebDriverResult<SwitchToFrameParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::UnknownError, >- "Message body was not an object"); >- let id = try!(FrameId::from_json(try_opt!(data.get("id"), >- ErrorStatus::UnknownError, >- "Missing 'id' parameter"))); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::UnknownError, >+ "Message body was not an object" >+ ); >+ let id = try!(FrameId::from_json(try_opt!( >+ data.get("id"), >+ ErrorStatus::UnknownError, >+ "Missing 'id' parameter" >+ ))); > >- Ok(SwitchToFrameParameters { >- id: id >- }) >+ Ok(SwitchToFrameParameters { id: id }) > } > } > > impl ToJson for SwitchToFrameParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("id".to_string(), self.id.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct SendKeysParameters { >- pub text: String >+ pub text: String, > } > > impl Parameters for SendKeysParameters { > fn from_json(body: &Json) -> WebDriverResult<SendKeysParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Message body was not an object"); >- let text = try_opt!(try_opt!(data.get("text"), >- ErrorStatus::InvalidArgument, >- "Missing 'text' parameter").as_string(), >- ErrorStatus::InvalidArgument, >- "Could not convert 'text' to string"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); >+ let text = try_opt!( >+ try_opt!( >+ data.get("text"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'text' parameter" >+ ).as_string(), >+ ErrorStatus::InvalidArgument, >+ "Could not convert 'text' to string" >+ ); > >- Ok(SendKeysParameters { >- text: text.into() >- }) >+ Ok(SendKeysParameters { text: text.into() }) > } > } > > impl ToJson for SendKeysParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("value".to_string(), self.text.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct JavascriptCommandParameters { > pub script: String, >- pub args: Nullable<Vec<Json>> >+ pub args: Nullable<Vec<Json>>, > } > > impl Parameters for JavascriptCommandParameters { > fn from_json(body: &Json) -> WebDriverResult<JavascriptCommandParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); > >- let args_json = try_opt!(data.get("args"), >- ErrorStatus::InvalidArgument, >- "Missing args parameter"); >+ let args_json = try_opt!( >+ data.get("args"), >+ ErrorStatus::InvalidArgument, >+ "Missing args parameter" >+ ); > >- let args = try!(Nullable::from_json( >- args_json, >- |x| { >- Ok((try_opt!(x.as_array(), >- ErrorStatus::InvalidArgument, >- "Failed to convert args to Array")).clone()) >- })); >+ let args = try!(Nullable::from_json(args_json, |x| Ok((try_opt!( >+ x.as_array(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert args to Array" >+ )).clone()))); > >- //TODO: Look for WebElements in args? >+ //TODO: Look for WebElements in args? > let script = try_opt!( >- try_opt!(data.get("script"), >- ErrorStatus::InvalidArgument, >- "Missing script parameter").as_string(), >+ try_opt!( >+ data.get("script"), >+ ErrorStatus::InvalidArgument, >+ "Missing script parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "Failed to convert script to String"); >+ "Failed to convert script to String" >+ ); > Ok(JavascriptCommandParameters { > script: script.to_string(), >- args: args.clone() >+ args: args.clone(), > }) > } > } > > impl ToJson for JavascriptCommandParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > //TODO: Wrap script so that it becomes marionette-compatible >@@ -869,28 +956,31 @@ impl ToJson for JavascriptCommandParameters { > > #[derive(Debug, PartialEq)] > pub struct GetNamedCookieParameters { > pub name: Nullable<String>, > } > > impl Parameters for GetNamedCookieParameters { > fn from_json(body: &Json) -> WebDriverResult<GetNamedCookieParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Message body was not an object"); >- let name_json = try_opt!(data.get("name"), >- ErrorStatus::InvalidArgument, >- "Missing 'name' parameter"); >- let name = try!(Nullable::from_json(name_json, |x| { >- Ok(try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "Failed to convert name to string") >- .to_string()) >- })); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); >+ let name_json = try_opt!( >+ data.get("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'name' parameter" >+ ); >+ let name = try!(Nullable::from_json(name_json, |x| Ok(try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert name to string" >+ ).to_string()))); > return Ok(GetNamedCookieParameters { name: name }); > } > } > > impl ToJson for GetNamedCookieParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("name".to_string(), self.name.to_json()); >@@ -901,106 +991,110 @@ impl ToJson for GetNamedCookieParameters { > #[derive(Debug, PartialEq)] > pub struct AddCookieParameters { > pub name: String, > pub value: String, > pub path: Nullable<String>, > pub domain: Nullable<String>, > pub expiry: Nullable<Date>, > pub secure: bool, >- pub httpOnly: bool >+ pub httpOnly: bool, > } > > impl Parameters for AddCookieParameters { > fn from_json(body: &Json) -> WebDriverResult<AddCookieParameters> { > if !body.is_object() { >- return Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- "Message body was not an object")); >+ return Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object", >+ )); > } > >- let data = try_opt!(body.find("cookie").and_then(|x| x.as_object()), >- ErrorStatus::InvalidArgument, >- "Cookie parameter not found or not an object"); >+ let data = try_opt!( >+ body.find("cookie").and_then(|x| x.as_object()), >+ ErrorStatus::InvalidArgument, >+ "Cookie parameter not found or not an object" >+ ); > > let name = try_opt!( >- try_opt!(data.get("name"), >- ErrorStatus::InvalidArgument, >- "Missing 'name' parameter").as_string(), >+ try_opt!( >+ data.get("name"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'name' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "'name' is not a string").to_string(); >+ "'name' is not a string" >+ ).to_string(); > > let value = try_opt!( >- try_opt!(data.get("value"), >- ErrorStatus::InvalidArgument, >- "Missing 'value' parameter").as_string(), >+ try_opt!( >+ data.get("value"), >+ ErrorStatus::InvalidArgument, >+ "Missing 'value' parameter" >+ ).as_string(), > ErrorStatus::InvalidArgument, >- "'value' is not a string").to_string(); >+ "'value' is not a string" >+ ).to_string(); > > let path = match data.get("path") { >- Some(path_json) => { >- try!(Nullable::from_json( >- path_json, >- |x| { >- Ok(try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "Failed to convert path to String").to_string()) >- })) >- }, >- None => Nullable::Null >+ Some(path_json) => try!(Nullable::from_json(path_json, |x| Ok(try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert path to String" >+ ).to_string()))), >+ None => Nullable::Null, > }; > > let domain = match data.get("domain") { >- Some(domain_json) => { >- try!(Nullable::from_json( >- domain_json, >- |x| { >- Ok(try_opt!(x.as_string(), >- ErrorStatus::InvalidArgument, >- "Failed to convert domain to String").to_string()) >- })) >- }, >- None => Nullable::Null >+ Some(domain_json) => try!(Nullable::from_json(domain_json, |x| Ok(try_opt!( >+ x.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert domain to String" >+ ).to_string()))), >+ None => Nullable::Null, > }; > > let expiry = match data.get("expiry") { >- Some(expiry_json) => { >- try!(Nullable::from_json( >- expiry_json, >- |x| { >- Ok(Date::new(try_opt!(x.as_u64(), >- ErrorStatus::InvalidArgument, >- "Failed to convert expiry to Date"))) >- })) >- }, >- None => Nullable::Null >+ Some(expiry_json) => try!(Nullable::from_json(expiry_json, |x| Ok(Date::new( >+ try_opt!( >+ x.as_u64(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert expiry to Date" >+ ) >+ )))), >+ None => Nullable::Null, > }; > > let secure = match data.get("secure") { >- Some(x) => try_opt!(x.as_boolean(), >- ErrorStatus::InvalidArgument, >- "Failed to convert secure to boolean"), >- None => false >+ Some(x) => try_opt!( >+ x.as_boolean(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert secure to boolean" >+ ), >+ None => false, > }; > > let http_only = match data.get("httpOnly") { >- Some(x) => try_opt!(x.as_boolean(), >- ErrorStatus::InvalidArgument, >- "Failed to convert httpOnly to boolean"), >- None => false >+ Some(x) => try_opt!( >+ x.as_boolean(), >+ ErrorStatus::InvalidArgument, >+ "Failed to convert httpOnly to boolean" >+ ), >+ None => false, > }; > > return Ok(AddCookieParameters { > name: name, > value: value, > path: path, > domain: domain, > expiry: expiry, > secure: secure, >- httpOnly: http_only >- }) >+ httpOnly: http_only, >+ }); > } > } > > impl ToJson for AddCookieParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("name".to_string(), self.name.to_json()); > data.insert("value".to_string(), self.value.to_json()); >@@ -1010,87 +1104,94 @@ impl ToJson for AddCookieParameters { > data.insert("secure".to_string(), self.secure.to_json()); > data.insert("httpOnly".to_string(), self.httpOnly.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct TakeScreenshotParameters { >- pub element: Nullable<WebElement> >+ pub element: Nullable<WebElement>, > } > > impl Parameters for TakeScreenshotParameters { > fn from_json(body: &Json) -> WebDriverResult<TakeScreenshotParameters> { >- let data = try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Message body was not an object"); >+ let data = try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); > let element = match data.get("element") { >- Some(element_json) => try!(Nullable::from_json( >- element_json, >- |x| { >- Ok(try!(WebElement::from_json(x))) >- })), >- None => Nullable::Null >+ Some(element_json) => try!(Nullable::from_json(element_json, |x| Ok(try!( >+ WebElement::from_json(x) >+ )))), >+ None => Nullable::Null, > }; > >- return Ok(TakeScreenshotParameters { >- element: element >- }) >+ return Ok(TakeScreenshotParameters { element: element }); > } > } > > impl ToJson for TakeScreenshotParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert("element".to_string(), self.element.to_json()); > Json::Object(data) > } > } > > #[derive(Debug, PartialEq)] > pub struct ActionsParameters { >- pub actions: Vec<ActionSequence> >+ pub actions: Vec<ActionSequence>, > } > > impl Parameters for ActionsParameters { > fn from_json(body: &Json) -> WebDriverResult<ActionsParameters> { >- try_opt!(body.as_object(), >- ErrorStatus::InvalidArgument, >- "Message body was not an object"); >+ try_opt!( >+ body.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Message body was not an object" >+ ); > let actions = try_opt!( >- try_opt!(body.find("actions"), >- ErrorStatus::InvalidArgument, >- "No actions parameter found").as_array(), >+ try_opt!( >+ body.find("actions"), >+ ErrorStatus::InvalidArgument, >+ "No actions parameter found" >+ ).as_array(), > ErrorStatus::InvalidArgument, >- "Parameter 'actions' was not an array"); >+ "Parameter 'actions' was not an array" >+ ); > > let mut result = Vec::with_capacity(actions.len()); > for chain in actions.iter() { > result.push(try!(ActionSequence::from_json(chain))); > } >- Ok(ActionsParameters { >- actions: result >- }) >+ Ok(ActionsParameters { actions: result }) > } > } > > impl ToJson for ActionsParameters { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); >- data.insert("actions".to_owned(), >- self.actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>().to_json()); >+ data.insert( >+ "actions".to_owned(), >+ self.actions >+ .iter() >+ .map(|x| x.to_json()) >+ .collect::<Vec<Json>>() >+ .to_json(), >+ ); > Json::Object(data) > } > } > > #[cfg(test)] > mod tests { >- use rustc_serialize::json::Json; > use super::{Nullable, Parameters, WindowRectParameters}; >+ use rustc_serialize::json::Json; > > #[test] > fn test_window_rect() { > let expected = WindowRectParameters { > x: Nullable::Value(0i32), > y: Nullable::Value(1i32), > width: Nullable::Value(2i32), > height: Nullable::Value(3i32), >@@ -1126,12 +1227,13 @@ mod tests { > #[test] > fn test_window_rect_floats() { > let expected = WindowRectParameters { > x: Nullable::Value(1i32), > y: Nullable::Value(2i32), > width: Nullable::Value(3i32), > height: Nullable::Value(4i32), > }; >- let actual = Json::from_str(r#"{"x": 1.1, "y": 2.2, "width": 3.3, "height": 4.4}"#).unwrap(); >+ let actual = >+ Json::from_str(r#"{"x": 1.1, "y": 2.2, "width": 3.3, "height": 4.4}"#).unwrap(); > assert_eq!(expected, Parameters::from_json(&actual).unwrap()); > } > } >diff --git a/testing/webdriver/src/common.rs b/testing/webdriver/src/common.rs >index 5a0f3398baa2..c13f3d28abcf 100644 >--- a/testing/webdriver/src/common.rs >+++ b/testing/webdriver/src/common.rs >@@ -1,13 +1,13 @@ >-use rustc_serialize::{Encodable, Encoder}; > use rustc_serialize::json::{Json, ToJson}; >+use rustc_serialize::{Encodable, Encoder}; > use std::collections::BTreeMap; > >-use error::{WebDriverResult, WebDriverError, ErrorStatus}; >+use error::{ErrorStatus, WebDriverError, WebDriverResult}; > > pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf"; > pub static FRAME_KEY: &'static str = "frame-075b-4da1-b6ba-e579c2d3230a"; > pub static WINDOW_KEY: &'static str = "window-fcc6-11e5-b4f8-330a88ab9d7f"; > > #[derive(Clone, Debug, PartialEq, RustcEncodable)] > pub struct Date(pub u64); > >@@ -22,203 +22,217 @@ impl ToJson for Date { > let &Date(x) = self; > x.to_json() > } > } > > #[derive(Clone, Debug, PartialEq)] > pub enum Nullable<T: ToJson> { > Value(T), >- Null >+ Null, > } > > impl<T: ToJson> Nullable<T> { >- pub fn is_null(&self) -> bool { >+ pub fn is_null(&self) -> bool { > match *self { > Nullable::Value(_) => false, >- Nullable::Null => true >+ Nullable::Null => true, > } > } > >- pub fn is_value(&self) -> bool { >+ pub fn is_value(&self) -> bool { > match *self { > Nullable::Value(_) => true, >- Nullable::Null => false >+ Nullable::Null => false, > } > } > > pub fn map<F, U: ToJson>(self, f: F) -> Nullable<U> >- where F: FnOnce(T) -> U { >+ where >+ F: FnOnce(T) -> U, >+ { > match self { > Nullable::Value(val) => Nullable::Value(f(val)), >- Nullable::Null => Nullable::Null >+ Nullable::Null => Nullable::Null, > } > } > } > > impl<T: ToJson> Nullable<T> { > //This is not very pretty >- pub fn from_json<F: FnOnce(&Json) -> WebDriverResult<T>>(value: &Json, f: F) -> WebDriverResult<Nullable<T>> { >+ pub fn from_json<F: FnOnce(&Json) -> WebDriverResult<T>>( >+ value: &Json, >+ f: F, >+ ) -> WebDriverResult<Nullable<T>> { > if value.is_null() { > Ok(Nullable::Null) > } else { > Ok(Nullable::Value(try!(f(value)))) > } > } > } > > impl<T: ToJson> ToJson for Nullable<T> { > fn to_json(&self) -> Json { > match *self { > Nullable::Value(ref x) => x.to_json(), >- Nullable::Null => Json::Null >+ Nullable::Null => Json::Null, > } > } > } > > impl<T: ToJson> Encodable for Nullable<T> { > fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { > match *self { > Nullable::Value(ref x) => x.to_json().encode(s), >- Nullable::Null => s.emit_option_none() >+ Nullable::Null => s.emit_option_none(), > } > } > } > > impl<T: ToJson> Into<Option<T>> for Nullable<T> { > fn into(self) -> Option<T> { > match self { > Nullable::Value(val) => Some(val), >- Nullable::Null => None >+ Nullable::Null => None, > } > } > } > > impl<T: ToJson> From<Option<T>> for Nullable<T> { > fn from(option: Option<T>) -> Nullable<T> { > match option { > Some(val) => Nullable::Value(val), > None => Nullable::Null, > } > } > } > > #[derive(Clone, Debug, PartialEq)] > pub struct WebElement { >- pub id: String >+ pub id: String, > } > > impl WebElement { > pub fn new(id: String) -> WebElement { >- WebElement { >- id: id >- } >+ WebElement { id: id } > } > > pub fn from_json(data: &Json) -> WebDriverResult<WebElement> { >- let object = try_opt!(data.as_object(), >- ErrorStatus::InvalidArgument, >- "Could not convert webelement to object"); >- let id_value = try_opt!(object.get(ELEMENT_KEY), >- ErrorStatus::InvalidArgument, >- "Could not find webelement key"); >+ let object = try_opt!( >+ data.as_object(), >+ ErrorStatus::InvalidArgument, >+ "Could not convert webelement to object" >+ ); >+ let id_value = try_opt!( >+ object.get(ELEMENT_KEY), >+ ErrorStatus::InvalidArgument, >+ "Could not find webelement key" >+ ); > >- let id = try_opt!(id_value.as_string(), >- ErrorStatus::InvalidArgument, >- "Could not convert web element to string").to_string(); >+ let id = try_opt!( >+ id_value.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Could not convert web element to string" >+ ).to_string(); > > Ok(WebElement::new(id)) > } > } > > impl ToJson for WebElement { > fn to_json(&self) -> Json { > let mut data = BTreeMap::new(); > data.insert(ELEMENT_KEY.to_string(), self.id.to_json()); > Json::Object(data) > } > } > >-impl <T> From<T> for WebElement >- where T: Into<String> { >+impl<T> From<T> for WebElement >+where >+ T: Into<String>, >+{ > fn from(data: T) -> WebElement { > WebElement::new(data.into()) > } > } > > #[derive(Debug, PartialEq)] > pub enum FrameId { > Short(u16), > Element(WebElement), >- Null >+ Null, > } > > impl FrameId { > pub fn from_json(data: &Json) -> WebDriverResult<FrameId> { > match data { > &Json::U64(x) => { > if x > u16::max_value() as u64 || x < u16::min_value() as u64 { >- return Err(WebDriverError::new(ErrorStatus::NoSuchFrame, >- "frame id out of range")) >+ return Err(WebDriverError::new( >+ ErrorStatus::NoSuchFrame, >+ "frame id out of range", >+ )); > }; > Ok(FrameId::Short(x as u16)) >- }, >+ } > &Json::Null => Ok(FrameId::Null), >- &Json::Object(_) => Ok(FrameId::Element( >- try!(WebElement::from_json(data)))), >- _ => Err(WebDriverError::new(ErrorStatus::NoSuchFrame, >- "frame id has unexpected type")) >+ &Json::Object(_) => Ok(FrameId::Element(try!(WebElement::from_json(data)))), >+ _ => Err(WebDriverError::new( >+ ErrorStatus::NoSuchFrame, >+ "frame id has unexpected type", >+ )), > } > } > } > > impl ToJson for FrameId { > fn to_json(&self) -> Json { > match *self { >- FrameId::Short(x) => { >- Json::U64(x as u64) >- }, >- FrameId::Element(ref x) => { >- Json::String(x.id.clone()) >- }, >- FrameId::Null => { >- Json::Null >- } >+ FrameId::Short(x) => Json::U64(x as u64), >+ FrameId::Element(ref x) => Json::String(x.id.clone()), >+ FrameId::Null => Json::Null, > } > } > } > > #[derive(Debug, PartialEq)] > pub enum LocatorStrategy { > CSSSelector, > LinkText, > PartialLinkText, > TagName, > XPath, > } > > impl LocatorStrategy { > pub fn from_json(body: &Json) -> WebDriverResult<LocatorStrategy> { >- match try_opt!(body.as_string(), >- ErrorStatus::InvalidArgument, >- "Expected locator strategy as string") { >+ match try_opt!( >+ body.as_string(), >+ ErrorStatus::InvalidArgument, >+ "Expected locator strategy as string" >+ ) { > "css selector" => Ok(LocatorStrategy::CSSSelector), > "link text" => Ok(LocatorStrategy::LinkText), > "partial link text" => Ok(LocatorStrategy::PartialLinkText), > "tag name" => Ok(LocatorStrategy::TagName), > "xpath" => Ok(LocatorStrategy::XPath), >- x => Err(WebDriverError::new(ErrorStatus::InvalidArgument, >- format!("Unknown locator strategy {}", x))) >+ x => Err(WebDriverError::new( >+ ErrorStatus::InvalidArgument, >+ format!("Unknown locator strategy {}", x), >+ )), > } > } > } > > impl ToJson for LocatorStrategy { > fn to_json(&self) -> Json { >- Json::String(match *self { >- LocatorStrategy::CSSSelector => "css selector", >- LocatorStrategy::LinkText => "link text", >- LocatorStrategy::PartialLinkText => "partial link text", >- LocatorStrategy::TagName => "tag name", >- LocatorStrategy::XPath => "xpath" >- }.to_string()) >+ Json::String( >+ match *self { >+ LocatorStrategy::CSSSelector => "css selector", >+ LocatorStrategy::LinkText => "link text", >+ LocatorStrategy::PartialLinkText => "partial link text", >+ LocatorStrategy::TagName => "tag name", >+ LocatorStrategy::XPath => "xpath", >+ }.to_string(), >+ ) > } > } >diff --git a/testing/webdriver/src/error.rs b/testing/webdriver/src/error.rs >index 0533cb246e23..4183e10f1ec5 100644 >--- a/testing/webdriver/src/error.rs >+++ b/testing/webdriver/src/error.rs >@@ -164,18 +164,17 @@ impl ErrorStatus { > NoSuchWindow => "no such window", > ScriptTimeout => "script timeout", > SessionNotCreated => "session not created", > StaleElementReference => "stale element reference", > Timeout => "timeout", > UnableToCaptureScreen => "unable to capture screen", > UnableToSetCookie => "unable to set cookie", > UnexpectedAlertOpen => "unexpected alert open", >- UnknownCommand | >- UnknownError => "unknown error", >+ UnknownCommand | UnknownError => "unknown error", > UnknownMethod => "unknown method", > UnknownPath => "unknown command", > UnsupportedOperation => "unsupported operation", > } > } > > /// Returns the correct HTTP status code associated with the error type. > pub fn http_status(&self) -> StatusCode { >@@ -258,28 +257,30 @@ pub struct WebDriverError { > pub error: ErrorStatus, > pub message: Cow<'static, str>, > pub stack: Cow<'static, str>, > pub delete_session: bool, > } > > impl WebDriverError { > pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError >- where S: Into<Cow<'static, str>> >+ where >+ S: Into<Cow<'static, str>>, > { > WebDriverError { > error: error, > message: message.into(), > stack: "".into(), > delete_session: false, > } > } > > pub fn new_with_stack<S>(error: ErrorStatus, message: S, stack: S) -> WebDriverError >- where S: Into<Cow<'static, str>> >+ where >+ S: Into<Cow<'static, str>>, > { > WebDriverError { > error: error, > message: message.into(), > stack: stack.into(), > delete_session: false, > } > } >diff --git a/testing/webdriver/src/httpapi.rs b/testing/webdriver/src/httpapi.rs >index f16a440acfda..957ab0645e8d 100644 >--- a/testing/webdriver/src/httpapi.rs >+++ b/testing/webdriver/src/httpapi.rs >@@ -1,99 +1,250 @@ >-use regex::{Regex, Captures}; >+use regex::{Captures, Regex}; > use rustc_serialize::json::Json; > > use hyper::method::Method; >-use hyper::method::Method::{Get, Post, Delete}; >+use hyper::method::Method::{Delete, Get, Post}; > >-use command::{WebDriverCommand, WebDriverMessage, WebDriverExtensionCommand, >- VoidWebDriverExtensionCommand}; >-use error::{WebDriverResult, WebDriverError, ErrorStatus}; >+use command::{ >+ VoidWebDriverExtensionCommand, WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage, >+}; >+use error::{ErrorStatus, WebDriverError, WebDriverResult}; > >-fn standard_routes<U:WebDriverExtensionRoute>() -> Vec<(Method, &'static str, Route<U>)> { >- return vec![(Post, "/session", Route::NewSession), >- (Delete, "/session/{sessionId}", Route::DeleteSession), >- (Post, "/session/{sessionId}/url", Route::Get), >- (Get, "/session/{sessionId}/url", Route::GetCurrentUrl), >- (Post, "/session/{sessionId}/back", Route::GoBack), >- (Post, "/session/{sessionId}/forward", Route::GoForward), >- (Post, "/session/{sessionId}/refresh", Route::Refresh), >- (Get, "/session/{sessionId}/title", Route::GetTitle), >- (Get, "/session/{sessionId}/source", Route::GetPageSource), >- (Get, "/session/{sessionId}/window", Route::GetWindowHandle), >- (Get, "/session/{sessionId}/window/handles", Route::GetWindowHandles), >- (Delete, "/session/{sessionId}/window", Route::CloseWindow), >- (Get, "/session/{sessionId}/window/size", Route::GetWindowSize), >- (Post, "/session/{sessionId}/window/size", Route::SetWindowSize), >- (Get, "/session/{sessionId}/window/position", Route::GetWindowPosition), >- (Post, "/session/{sessionId}/window/position", Route::SetWindowPosition), >- (Get, "/session/{sessionId}/window/rect", Route::GetWindowRect), >- (Post, "/session/{sessionId}/window/rect", Route::SetWindowRect), >- (Post, "/session/{sessionId}/window/minimize", Route::MinimizeWindow), >- (Post, "/session/{sessionId}/window/maximize", Route::MaximizeWindow), >- (Post, "/session/{sessionId}/window/fullscreen", Route::FullscreenWindow), >- (Post, "/session/{sessionId}/window", Route::SwitchToWindow), >- (Post, "/session/{sessionId}/frame", Route::SwitchToFrame), >- (Post, "/session/{sessionId}/frame/parent", Route::SwitchToParentFrame), >- (Post, "/session/{sessionId}/element", Route::FindElement), >- (Post, "/session/{sessionId}/elements", Route::FindElements), >- (Post, "/session/{sessionId}/element/{elementId}/element", Route::FindElementElement), >- (Post, "/session/{sessionId}/element/{elementId}/elements", Route::FindElementElements), >- (Get, "/session/{sessionId}/element/active", Route::GetActiveElement), >- (Get, "/session/{sessionId}/element/{elementId}/displayed", Route::IsDisplayed), >- (Get, "/session/{sessionId}/element/{elementId}/selected", Route::IsSelected), >- (Get, "/session/{sessionId}/element/{elementId}/attribute/{name}", Route::GetElementAttribute), >- (Get, "/session/{sessionId}/element/{elementId}/property/{name}", Route::GetElementProperty), >- (Get, "/session/{sessionId}/element/{elementId}/css/{propertyName}", Route::GetCSSValue), >- (Get, "/session/{sessionId}/element/{elementId}/text", Route::GetElementText), >- (Get, "/session/{sessionId}/element/{elementId}/name", Route::GetElementTagName), >- (Get, "/session/{sessionId}/element/{elementId}/rect", Route::GetElementRect), >- (Get, "/session/{sessionId}/element/{elementId}/enabled", Route::IsEnabled), >- (Post, "/session/{sessionId}/execute/sync", Route::ExecuteScript), >- (Post, "/session/{sessionId}/execute/async", Route::ExecuteAsyncScript), >- (Get, "/session/{sessionId}/cookie", Route::GetCookies), >- (Get, "/session/{sessionId}/cookie/{name}", Route::GetNamedCookie), >- (Post, "/session/{sessionId}/cookie", Route::AddCookie), >- (Delete, "/session/{sessionId}/cookie", Route::DeleteCookies), >- (Delete, "/session/{sessionId}/cookie/{name}", Route::DeleteCookie), >- (Get, "/session/{sessionId}/timeouts", Route::GetTimeouts), >- (Post, "/session/{sessionId}/timeouts", Route::SetTimeouts), >- (Post, "/session/{sessionId}/element/{elementId}/click", Route::ElementClick), >- (Post, "/session/{sessionId}/element/{elementId}/tap", Route::ElementTap), >- (Post, "/session/{sessionId}/element/{elementId}/clear", Route::ElementClear), >- (Post, "/session/{sessionId}/element/{elementId}/value", Route::ElementSendKeys), >- (Post, "/session/{sessionId}/alert/dismiss", Route::DismissAlert), >- (Post, "/session/{sessionId}/alert/accept", Route::AcceptAlert), >- (Get, "/session/{sessionId}/alert/text", Route::GetAlertText), >- (Post, "/session/{sessionId}/alert/text", Route::SendAlertText), >- (Get, "/session/{sessionId}/screenshot", Route::TakeScreenshot), >- (Get, "/session/{sessionId}/element/{elementId}/screenshot", Route::TakeElementScreenshot), >- (Post, "/session/{sessionId}/actions", Route::PerformActions), >- (Delete, "/session/{sessionId}/actions", Route::ReleaseActions), >- (Get, "/status", Route::Status),] >+fn standard_routes<U: WebDriverExtensionRoute>() -> Vec<(Method, &'static str, Route<U>)> { >+ return vec![ >+ (Post, "/session", Route::NewSession), >+ (Delete, "/session/{sessionId}", Route::DeleteSession), >+ (Post, "/session/{sessionId}/url", Route::Get), >+ (Get, "/session/{sessionId}/url", Route::GetCurrentUrl), >+ (Post, "/session/{sessionId}/back", Route::GoBack), >+ (Post, "/session/{sessionId}/forward", Route::GoForward), >+ (Post, "/session/{sessionId}/refresh", Route::Refresh), >+ (Get, "/session/{sessionId}/title", Route::GetTitle), >+ (Get, "/session/{sessionId}/source", Route::GetPageSource), >+ (Get, "/session/{sessionId}/window", Route::GetWindowHandle), >+ ( >+ Get, >+ "/session/{sessionId}/window/handles", >+ Route::GetWindowHandles, >+ ), >+ (Delete, "/session/{sessionId}/window", Route::CloseWindow), >+ ( >+ Get, >+ "/session/{sessionId}/window/size", >+ Route::GetWindowSize, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/size", >+ Route::SetWindowSize, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/window/position", >+ Route::GetWindowPosition, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/position", >+ Route::SetWindowPosition, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/window/rect", >+ Route::GetWindowRect, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/rect", >+ Route::SetWindowRect, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/minimize", >+ Route::MinimizeWindow, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/maximize", >+ Route::MaximizeWindow, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/window/fullscreen", >+ Route::FullscreenWindow, >+ ), >+ (Post, "/session/{sessionId}/window", Route::SwitchToWindow), >+ (Post, "/session/{sessionId}/frame", Route::SwitchToFrame), >+ ( >+ Post, >+ "/session/{sessionId}/frame/parent", >+ Route::SwitchToParentFrame, >+ ), >+ (Post, "/session/{sessionId}/element", Route::FindElement), >+ (Post, "/session/{sessionId}/elements", Route::FindElements), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/element", >+ Route::FindElementElement, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/elements", >+ Route::FindElementElements, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/active", >+ Route::GetActiveElement, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/displayed", >+ Route::IsDisplayed, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/selected", >+ Route::IsSelected, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/attribute/{name}", >+ Route::GetElementAttribute, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/property/{name}", >+ Route::GetElementProperty, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/css/{propertyName}", >+ Route::GetCSSValue, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/text", >+ Route::GetElementText, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/name", >+ Route::GetElementTagName, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/rect", >+ Route::GetElementRect, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/enabled", >+ Route::IsEnabled, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/execute/sync", >+ Route::ExecuteScript, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/execute/async", >+ Route::ExecuteAsyncScript, >+ ), >+ (Get, "/session/{sessionId}/cookie", Route::GetCookies), >+ ( >+ Get, >+ "/session/{sessionId}/cookie/{name}", >+ Route::GetNamedCookie, >+ ), >+ (Post, "/session/{sessionId}/cookie", Route::AddCookie), >+ (Delete, "/session/{sessionId}/cookie", Route::DeleteCookies), >+ ( >+ Delete, >+ "/session/{sessionId}/cookie/{name}", >+ Route::DeleteCookie, >+ ), >+ (Get, "/session/{sessionId}/timeouts", Route::GetTimeouts), >+ (Post, "/session/{sessionId}/timeouts", Route::SetTimeouts), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/click", >+ Route::ElementClick, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/tap", >+ Route::ElementTap, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/clear", >+ Route::ElementClear, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/element/{elementId}/value", >+ Route::ElementSendKeys, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/alert/dismiss", >+ Route::DismissAlert, >+ ), >+ ( >+ Post, >+ "/session/{sessionId}/alert/accept", >+ Route::AcceptAlert, >+ ), >+ (Get, "/session/{sessionId}/alert/text", Route::GetAlertText), >+ ( >+ Post, >+ "/session/{sessionId}/alert/text", >+ Route::SendAlertText, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/screenshot", >+ Route::TakeScreenshot, >+ ), >+ ( >+ Get, >+ "/session/{sessionId}/element/{elementId}/screenshot", >+ Route::TakeElementScreenshot, >+ ), >+ (Post, "/session/{sessionId}/actions", Route::PerformActions), >+ ( >+ Delete, >+ "/session/{sessionId}/actions", >+ Route::ReleaseActions, >+ ), >+ (Get, "/status", Route::Status), >+ ]; > } > > #[derive(Clone, Copy, Debug)] >-pub enum Route<U:WebDriverExtensionRoute> { >+pub enum Route<U: WebDriverExtensionRoute> { > NewSession, > DeleteSession, > Get, > GetCurrentUrl, > GoBack, > GoForward, > Refresh, > GetTitle, > GetPageSource, > GetWindowHandle, > GetWindowHandles, > CloseWindow, >- GetWindowSize, // deprecated >- SetWindowSize, // deprecated >- GetWindowPosition, // deprecated >- SetWindowPosition, // deprecated >+ GetWindowSize, // deprecated >+ SetWindowSize, // deprecated >+ GetWindowPosition, // deprecated >+ SetWindowPosition, // deprecated > GetWindowRect, > SetWindowRect, > MinimizeWindow, > MaximizeWindow, > FullscreenWindow, > SwitchToWindow, > SwitchToFrame, > SwitchToParentFrame, >@@ -131,47 +282,51 @@ pub enum Route<U:WebDriverExtensionRoute> { > GetAlertText, > SendAlertText, > TakeScreenshot, > TakeElementScreenshot, > Status, > Extension(U), > } > >-pub trait WebDriverExtensionRoute : Clone + Send + PartialEq { >+pub trait WebDriverExtensionRoute: Clone + Send + PartialEq { > type Command: WebDriverExtensionCommand + 'static; > > fn command(&self, &Captures, &Json) -> WebDriverResult<WebDriverCommand<Self::Command>>; > } > > #[derive(Clone, Debug, PartialEq)] > pub struct VoidWebDriverExtensionRoute; > > impl WebDriverExtensionRoute for VoidWebDriverExtensionRoute { > type Command = VoidWebDriverExtensionCommand; > >- fn command(&self, _:&Captures, _:&Json) -> WebDriverResult<WebDriverCommand<VoidWebDriverExtensionCommand>> { >+ fn command( >+ &self, >+ _: &Captures, >+ _: &Json, >+ ) -> WebDriverResult<WebDriverCommand<VoidWebDriverExtensionCommand>> { > panic!("No extensions implemented"); > } > } > > #[derive(Clone, Debug)] > struct RequestMatcher<U: WebDriverExtensionRoute> { > method: Method, > path_regexp: Regex, >- match_type: Route<U> >+ match_type: Route<U>, > } > >-impl <U: WebDriverExtensionRoute> RequestMatcher<U> { >+impl<U: WebDriverExtensionRoute> RequestMatcher<U> { > pub fn new(method: Method, path: &str, match_type: Route<U>) -> RequestMatcher<U> { > let path_regexp = RequestMatcher::<U>::compile_path(path); > RequestMatcher { > method: method, > path_regexp: path_regexp, >- match_type: match_type >+ match_type: match_type, > } > } > > pub fn get_match<'t>(&'t self, method: Method, path: &'t str) -> (bool, Option<Captures>) { > let captures = self.path_regexp.captures(path); > (method == self.method, captures) > } > >@@ -179,17 +334,17 @@ impl <U: WebDriverExtensionRoute> RequestMatcher<U> { > let mut rv = String::new(); > rv.push_str("^"); > let components = path.split('/'); > for component in components { > if component.starts_with("{") { > if !component.ends_with("}") { > panic!("Invalid url pattern") > } >- rv.push_str(&format!("(?P<{}>[^/]+)/", &component[1..component.len()-1])[..]); >+ rv.push_str(&format!("(?P<{}>[^/]+)/", &component[1..component.len() - 1])[..]); > } else { > rv.push_str(&format!("{}/", component)[..]); > } > } > //Remove the trailing / > rv.pop(); > rv.push_str("$"); > //This will fail at runtime if the regexp is invalid >@@ -197,49 +352,60 @@ impl <U: WebDriverExtensionRoute> RequestMatcher<U> { > } > } > > #[derive(Debug)] > pub struct WebDriverHttpApi<U: WebDriverExtensionRoute> { > routes: Vec<(Method, RequestMatcher<U>)>, > } > >-impl <U: WebDriverExtensionRoute> WebDriverHttpApi<U> { >+impl<U: WebDriverExtensionRoute> WebDriverHttpApi<U> { > pub fn new(extension_routes: &[(Method, &str, U)]) -> WebDriverHttpApi<U> { >- let mut rv = WebDriverHttpApi::<U> { >- routes: vec![], >- }; >+ let mut rv = WebDriverHttpApi::<U> { routes: vec![] }; > debug!("Creating routes"); > for &(ref method, ref url, ref match_type) in standard_routes::<U>().iter() { > rv.add(method.clone(), *url, (*match_type).clone()); >- }; >+ } > for &(ref method, ref url, ref extension_route) in extension_routes.iter() { >- rv.add(method.clone(), *url, Route::Extension(extension_route.clone())); >- }; >+ rv.add( >+ method.clone(), >+ *url, >+ Route::Extension(extension_route.clone()), >+ ); >+ } > rv > } > > fn add(&mut self, method: Method, path: &str, match_type: Route<U>) { > let http_matcher = RequestMatcher::new(method.clone(), path, match_type); > self.routes.push((method, http_matcher)); > } > >- pub fn decode_request(&self, method: Method, path: &str, body: &str) -> WebDriverResult<WebDriverMessage<U>> { >+ pub fn decode_request( >+ &self, >+ method: Method, >+ path: &str, >+ body: &str, >+ ) -> WebDriverResult<WebDriverMessage<U>> { > let mut error = ErrorStatus::UnknownPath; > for &(ref match_method, ref matcher) in self.routes.iter() { > if method == *match_method { > let (method_match, captures) = matcher.get_match(method.clone(), path); > if captures.is_some() { > if method_match { >- return WebDriverMessage::from_http(matcher.match_type.clone(), >- &captures.unwrap(), >- body, >- method == Post) >+ return WebDriverMessage::from_http( >+ matcher.match_type.clone(), >+ &captures.unwrap(), >+ body, >+ method == Post, >+ ); > } else { > error = ErrorStatus::UnknownMethod; > } > } > } > } >- Err(WebDriverError::new(error, >- format!("{} {} did not match a known command", method, path))) >+ Err(WebDriverError::new( >+ error, >+ format!("{} {} did not match a known command", method, path), >+ )) > } > } >diff --git a/testing/webdriver/src/lib.rs b/testing/webdriver/src/lib.rs >index e708c72e5e3f..30a97925921d 100644 >--- a/testing/webdriver/src/lib.rs >+++ b/testing/webdriver/src/lib.rs >@@ -1,29 +1,30 @@ > #![allow(non_snake_case)] > > #[macro_use] > extern crate log; >-extern crate rustc_serialize; >+extern crate cookie; > extern crate hyper; > extern crate regex; >-extern crate cookie; >+extern crate rustc_serialize; > extern crate time; >-extern crate url; > extern crate unicode_segmentation; >+extern crate url; > >-#[macro_use] pub mod macros; >+#[macro_use] >+pub mod macros; > pub mod actions; >-pub mod httpapi; > pub mod capabilities; > pub mod command; > pub mod common; > pub mod error; >-pub mod server; >+pub mod httpapi; > pub mod response; >+pub mod server; > > #[cfg(test)] > mod nullable_tests { > use super::common::Nullable; > > #[test] > fn test_nullable_map() { > let mut test = Nullable::Value(21); >diff --git a/testing/webdriver/src/macros.rs b/testing/webdriver/src/macros.rs >index 46e97ae39ede..07a12978485d 100644 >--- a/testing/webdriver/src/macros.rs >+++ b/testing/webdriver/src/macros.rs >@@ -1,8 +1,8 @@ > macro_rules! try_opt { >- ($expr:expr, $err_type:expr, $err_msg:expr) => ({ >+ ($expr:expr, $err_type:expr, $err_msg:expr) => {{ > match $expr { > Some(x) => x, >- None => return Err(WebDriverError::new($err_type, $err_msg)) >+ None => return Err(WebDriverError::new($err_type, $err_msg)), > } >- }) >+ }}; > } >diff --git a/testing/webdriver/src/response.rs b/testing/webdriver/src/response.rs >index 4bd9ceccdc3e..a9d67e515fb1 100644 >--- a/testing/webdriver/src/response.rs >+++ b/testing/webdriver/src/response.rs >@@ -50,40 +50,44 @@ impl WebDriverResponse { > > #[derive(Debug, RustcEncodable)] > pub struct CloseWindowResponse { > pub window_handles: Vec<String>, > } > > impl CloseWindowResponse { > pub fn new(handles: Vec<String>) -> CloseWindowResponse { >- CloseWindowResponse { window_handles: handles } >+ CloseWindowResponse { >+ window_handles: handles, >+ } > } > } > > impl ToJson for CloseWindowResponse { > fn to_json(&self) -> Json { >- Json::Array(self.window_handles >- .iter() >- .map(|x| Json::String(x.clone())) >- .collect::<Vec<Json>>()) >+ Json::Array( >+ self.window_handles >+ .iter() >+ .map(|x| Json::String(x.clone())) >+ .collect::<Vec<Json>>(), >+ ) > } > } > > #[derive(Debug, RustcEncodable)] > pub struct NewSessionResponse { > pub sessionId: String, >- pub capabilities: json::Json >+ pub capabilities: json::Json, > } > > impl NewSessionResponse { > pub fn new(session_id: String, capabilities: json::Json) -> NewSessionResponse { > NewSessionResponse { > capabilities: capabilities, >- sessionId: session_id >+ sessionId: session_id, > } > } > } > > #[derive(Debug, RustcEncodable)] > pub struct TimeoutsResponse { > pub script: u64, > pub pageLoad: u64, >@@ -97,24 +101,22 @@ impl TimeoutsResponse { > pageLoad: page_load, > implicit: implicit, > } > } > } > > #[derive(Debug, RustcEncodable)] > pub struct ValueResponse { >- pub value: json::Json >+ pub value: json::Json, > } > > impl ValueResponse { > pub fn new(value: json::Json) -> ValueResponse { >- ValueResponse { >- value: value >- } >+ ValueResponse { value: value } > } > } > > #[derive(Debug, RustcEncodable)] > pub struct ElementRectResponse { > /// X axis position of the top-left corner of the element relative > // to the current browsing contextâs document element in CSS reference > // pixels. >@@ -213,33 +215,34 @@ pub struct CookieResponse { > > #[derive(Debug, RustcEncodable)] > pub struct CookiesResponse { > pub value: Vec<Cookie>, > } > > #[cfg(test)] > mod tests { >- use super::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, ElementRectResponse, >- NewSessionResponse, Nullable, TimeoutsResponse, ValueResponse, WebDriverResponse, >- WindowRectResponse}; >+ use super::{ >+ CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, ElementRectResponse, >+ NewSessionResponse, Nullable, TimeoutsResponse, ValueResponse, WebDriverResponse, >+ WindowRectResponse, >+ }; > use rustc_serialize::json::Json; > use std::collections::BTreeMap; > > fn test(resp: WebDriverResponse, expected_str: &str) { > let data = resp.to_json_string(); > let actual = Json::from_str(&*data).unwrap(); > let expected = Json::from_str(expected_str).unwrap(); > assert_eq!(actual, expected); > } > > #[test] > fn test_close_window() { >- let resp = WebDriverResponse::CloseWindow( >- CloseWindowResponse::new(vec!["test".into()])); >+ let resp = WebDriverResponse::CloseWindow(CloseWindowResponse::new(vec!["test".into()])); > let expected = r#"{"value": ["test"]}"#; > test(resp, expected); > } > > #[test] > fn test_cookie() { > let cookie = Cookie { > name: "name".into(), >@@ -254,27 +257,26 @@ mod tests { > let expected = r#"{"value": {"name": "name", "expiry": null, "value": "value", > "path": "/", "domain": null, "secure": true, "httpOnly": false}}"#; > test(resp, expected); > } > > #[test] > fn test_cookies() { > let resp = WebDriverResponse::Cookies(CookiesResponse { >- value: vec![ >- Cookie { >- name: "name".into(), >- value: "value".into(), >- path: Nullable::Value("/".into()), >- domain: Nullable::Null, >- expiry: Nullable::Null, >- secure: true, >- httpOnly: false, >- } >- ]}); >+ value: vec![Cookie { >+ name: "name".into(), >+ value: "value".into(), >+ path: Nullable::Value("/".into()), >+ domain: Nullable::Null, >+ expiry: Nullable::Null, >+ secure: true, >+ httpOnly: false, >+ }], >+ }); > let expected = r#"{"value": [{"name": "name", "value": "value", "path": "/", > "domain": null, "expiry": null, "secure": true, "httpOnly": false}]}"#; > test(resp, expected); > } > > #[test] > fn test_element_rect() { > let rect = ElementRectResponse { >@@ -298,33 +300,35 @@ mod tests { > }; > let resp = WebDriverResponse::WindowRect(rect); > let expected = r#"{"value": {"x": 0, "y": 1, "width": 2, "height": 3}}"#; > test(resp, expected); > } > > #[test] > fn test_new_session() { >- let resp = WebDriverResponse::NewSession( >- NewSessionResponse::new("test".into(), >- Json::Object(BTreeMap::new()))); >+ let resp = WebDriverResponse::NewSession(NewSessionResponse::new( >+ "test".into(), >+ Json::Object(BTreeMap::new()), >+ )); > let expected = r#"{"value": {"sessionId": "test", "capabilities": {}}}"#; > test(resp, expected); > } > > #[test] > fn test_timeouts() { >- let resp = WebDriverResponse::Timeouts(TimeoutsResponse::new( >- 1, 2, 3)); >+ let resp = WebDriverResponse::Timeouts(TimeoutsResponse::new(1, 2, 3)); > let expected = r#"{"value": {"script": 1, "pageLoad": 2, "implicit": 3}}"#; > test(resp, expected); > } > > #[test] > fn test_value() { > let mut value = BTreeMap::new(); >- value.insert("example".into(), Json::Array(vec![Json::String("test".into())])); >- let resp = WebDriverResponse::Generic(ValueResponse::new( >- Json::Object(value))); >+ value.insert( >+ "example".into(), >+ Json::Array(vec![Json::String("test".into())]), >+ ); >+ let resp = WebDriverResponse::Generic(ValueResponse::new(Json::Object(value))); > let expected = r#"{"value": {"example": ["test"]}}"#; > test(resp, expected); > } > } >diff --git a/testing/webdriver/src/server.rs b/testing/webdriver/src/server.rs >index c5fe98558f3b..bf0a0ea79242 100644 >--- a/testing/webdriver/src/server.rs >+++ b/testing/webdriver/src/server.rs >@@ -1,55 +1,59 @@ > use std::io::Read; > use std::marker::PhantomData; > use std::net::SocketAddr; > use std::sync::mpsc::{channel, Receiver, Sender}; > use std::sync::Mutex; > use std::thread; > use std::time::Duration; > >-use hyper::header::{ContentType, CacheControl, CacheDirective}; >-use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value}; >+use hyper::header::{CacheControl, CacheDirective, ContentType}; > use hyper::method::Method; >-use hyper::Result; >+use hyper::mime::{Attr, Mime, SubLevel, TopLevel, Value}; > use hyper::server::{Handler, Listening, Request, Response, Server}; > use hyper::status::StatusCode; > use hyper::uri::RequestUri::AbsolutePath; >+use hyper::Result; > >-use command::{WebDriverMessage, WebDriverCommand}; >-use error::{WebDriverResult, WebDriverError, ErrorStatus}; >-use httpapi::{WebDriverHttpApi, WebDriverExtensionRoute, VoidWebDriverExtensionRoute}; >+use command::{WebDriverCommand, WebDriverMessage}; >+use error::{ErrorStatus, WebDriverError, WebDriverResult}; >+use httpapi::{VoidWebDriverExtensionRoute, WebDriverExtensionRoute, WebDriverHttpApi}; > use response::{CloseWindowResponse, WebDriverResponse}; > > enum DispatchMessage<U: WebDriverExtensionRoute> { >- HandleWebDriver(WebDriverMessage<U>, Sender<WebDriverResult<WebDriverResponse>>), >- Quit >+ HandleWebDriver( >+ WebDriverMessage<U>, >+ Sender<WebDriverResult<WebDriverResponse>>, >+ ), >+ Quit, > } > > #[derive(Clone, Debug, PartialEq)] > pub struct Session { >- pub id: String >+ pub id: String, > } > > impl Session { > fn new(id: String) -> Session { >- Session { >- id: id >- } >+ Session { id: id } > } > } > >-pub trait WebDriverHandler<U: WebDriverExtensionRoute=VoidWebDriverExtensionRoute> : Send { >- fn handle_command(&mut self, session: &Option<Session>, msg: WebDriverMessage<U>) -> WebDriverResult<WebDriverResponse>; >+pub trait WebDriverHandler<U: WebDriverExtensionRoute = VoidWebDriverExtensionRoute>: Send { >+ fn handle_command( >+ &mut self, >+ session: &Option<Session>, >+ msg: WebDriverMessage<U>, >+ ) -> WebDriverResult<WebDriverResponse>; > fn delete_session(&mut self, session: &Option<Session>); > } > > #[derive(Debug)] >-struct Dispatcher<T: WebDriverHandler<U>, >- U: WebDriverExtensionRoute> { >+struct Dispatcher<T: WebDriverHandler<U>, U: WebDriverExtensionRoute> { > handler: T, > session: Option<Session>, > extension_type: PhantomData<U>, > } > > impl<T: WebDriverHandler<U>, U: WebDriverExtensionRoute> Dispatcher<T, U> { > fn new(handler: T) -> Dispatcher<T, U> { > Dispatcher { >@@ -67,17 +71,19 @@ impl<T: WebDriverHandler<U>, U: WebDriverExtensionRoute> Dispatcher<T, U> { > Ok(_) => self.handler.handle_command(&self.session, msg), > Err(e) => Err(e), > }; > > match resp { > Ok(WebDriverResponse::NewSession(ref new_session)) => { > self.session = Some(Session::new(new_session.sessionId.clone())); > } >- Ok(WebDriverResponse::CloseWindow(CloseWindowResponse { ref window_handles })) => { >+ Ok(WebDriverResponse::CloseWindow(CloseWindowResponse { >+ ref window_handles, >+ })) => { > if window_handles.len() == 0 { > debug!("Last window was closed, deleting session"); > self.delete_session(); > } > } > Ok(WebDriverResponse::DeleteSession) => self.delete_session(), > Err(ref x) if x.delete_session => self.delete_session(), > _ => {} >@@ -96,76 +102,73 @@ impl<T: WebDriverHandler<U>, U: WebDriverExtensionRoute> Dispatcher<T, U> { > fn delete_session(&mut self) { > debug!("Deleting session"); > self.handler.delete_session(&self.session); > self.session = None; > } > > fn check_session(&self, msg: &WebDriverMessage<U>) -> WebDriverResult<()> { > match msg.session_id { >- Some(ref msg_session_id) => { >- match self.session { >- Some(ref existing_session) => { >- if existing_session.id != *msg_session_id { >- Err(WebDriverError::new( >- ErrorStatus::InvalidSessionId, >- format!("Got unexpected session id {}", >- msg_session_id))) >- } else { >- Ok(()) >- } >- }, >- None => Ok(()) >+ Some(ref msg_session_id) => match self.session { >+ Some(ref existing_session) => { >+ if existing_session.id != *msg_session_id { >+ Err(WebDriverError::new( >+ ErrorStatus::InvalidSessionId, >+ format!("Got unexpected session id {}", msg_session_id), >+ )) >+ } else { >+ Ok(()) >+ } > } >+ None => Ok(()), > }, > None => { > match self.session { > Some(_) => { > match msg.command { > WebDriverCommand::Status => Ok(()), >- WebDriverCommand::NewSession(_) => { >- Err(WebDriverError::new( >- ErrorStatus::SessionNotCreated, >- "Session is already started")) >- }, >+ WebDriverCommand::NewSession(_) => Err(WebDriverError::new( >+ ErrorStatus::SessionNotCreated, >+ "Session is already started", >+ )), > _ => { > //This should be impossible > error!("Got a message with no session id"); > Err(WebDriverError::new( > ErrorStatus::UnknownError, >- "Got a command with no session?!")) >+ "Got a command with no session?!", >+ )) > } > } >- }, >- None => { >- match msg.command { >- WebDriverCommand::NewSession(_) => Ok(()), >- WebDriverCommand::Status => Ok(()), >- _ => Err(WebDriverError::new( >- ErrorStatus::InvalidSessionId, >- "Tried to run a command before creating a session")) >- } > } >+ None => match msg.command { >+ WebDriverCommand::NewSession(_) => Ok(()), >+ WebDriverCommand::Status => Ok(()), >+ _ => Err(WebDriverError::new( >+ ErrorStatus::InvalidSessionId, >+ "Tried to run a command before creating a session", >+ )), >+ }, > } > } > } > } > } > > #[derive(Debug)] > struct HttpHandler<U: WebDriverExtensionRoute> { > chan: Mutex<Sender<DispatchMessage<U>>>, >- api: Mutex<WebDriverHttpApi<U>> >+ api: Mutex<WebDriverHttpApi<U>>, > } > >-impl <U: WebDriverExtensionRoute> HttpHandler<U> { >+impl<U: WebDriverExtensionRoute> HttpHandler<U> { > fn new(api: WebDriverHttpApi<U>, chan: Sender<DispatchMessage<U>>) -> HttpHandler<U> { > HttpHandler { > chan: Mutex::new(chan), >- api: Mutex::new(api) >+ api: Mutex::new(api), > } > } > } > > impl<U: WebDriverExtensionRoute> Handler for HttpHandler<U> { > fn handle(&self, req: Request, res: Response) { > let mut req = req; > let mut res = res; >@@ -203,38 +206,37 @@ impl<U: WebDriverExtensionRoute> Handler for HttpHandler<U> { > } > } > Err(_) => { > error!("Something terrible happened"); > return; > } > } > match recv_res.recv() { >- Ok(data) => { >- match data { >- Ok(response) => (StatusCode::Ok, response.to_json_string()), >- Err(err) => (err.http_status(), err.to_json_string()), >- } >- } >+ Ok(data) => match data { >+ Ok(response) => (StatusCode::Ok, response.to_json_string()), >+ Err(err) => (err.http_status(), err.to_json_string()), >+ }, > Err(e) => panic!("Error reading response: {:?}", e), > } > } > Err(err) => (err.http_status(), err.to_json_string()), > }; > > debug!("<- {} {}", status, resp_body); > > { > let resp_status = res.status_mut(); > *resp_status = status; > } >- res.headers_mut() >- .set(ContentType(Mime(TopLevel::Application, >- SubLevel::Json, >- vec![(Attr::Charset, Value::Utf8)]))); >+ res.headers_mut().set(ContentType(Mime( >+ TopLevel::Application, >+ SubLevel::Json, >+ vec![(Attr::Charset, Value::Utf8)], >+ ))); > res.headers_mut() > .set(CacheControl(vec![CacheDirective::NoCache])); > > res.send(&resp_body.as_bytes()).unwrap(); > } > _ => {} > } > } >diff --git a/toolkit/crashreporter/rust/lib.rs b/toolkit/crashreporter/rust/lib.rs >index d0fc77099b41..d5377ac3da6f 100644 >--- a/toolkit/crashreporter/rust/lib.rs >+++ b/toolkit/crashreporter/rust/lib.rs >@@ -3,23 +3,26 @@ extern crate rustc_demangle; > use rustc_demangle::demangle; > use std::ffi::{CStr, CString}; > use std::ptr; > > /// Demangle `name` as a Rust symbol. > /// > /// The resulting pointer should be freed with `free_demangled_name`. > #[no_mangle] >-pub extern fn rust_demangle(name: *const std::os::raw::c_char) -> *mut std::os::raw::c_char { >- let demangled = format!("{:#}", demangle(&unsafe { CStr::from_ptr(name) }.to_string_lossy())); >+pub extern "C" fn rust_demangle(name: *const std::os::raw::c_char) -> *mut std::os::raw::c_char { >+ let demangled = format!( >+ "{:#}", >+ demangle(&unsafe { CStr::from_ptr(name) }.to_string_lossy()) >+ ); > CString::new(demangled) > .map(|s| s.into_raw()) > .unwrap_or(ptr::null_mut()) > } > > /// Free a string that was returned from `rust_demangle`. > #[no_mangle] >-pub extern fn free_rust_demangled_name(demangled: *mut std::os::raw::c_char) { >+pub extern "C" fn free_rust_demangled_name(demangled: *mut std::os::raw::c_char) { > if demangled != ptr::null_mut() { > // Just take ownership here. > unsafe { CString::from_raw(demangled) }; > } > } >diff --git a/toolkit/library/rust/shared/build.rs b/toolkit/library/rust/shared/build.rs >index afae7d37abf3..e878185f8ec3 100644 >--- a/toolkit/library/rust/shared/build.rs >+++ b/toolkit/library/rust/shared/build.rs >@@ -4,20 +4,24 @@ use rustc_version::{version, Version}; > > fn main() { > let ver = version().unwrap(); > let mut bootstrap = false; > > if ver >= Version::parse("1.24.0").unwrap() && ver < Version::parse("1.27.0").unwrap() { > println!("cargo:rustc-cfg=feature=\"oom_with_global_alloc\""); > bootstrap = true; >- } else if ver >= Version::parse("1.28.0-alpha").unwrap() && ver < Version::parse("1.30.0-alpha").unwrap() { >+ } else if ver >= Version::parse("1.28.0-alpha").unwrap() >+ && ver < Version::parse("1.30.0-alpha").unwrap() >+ { > println!("cargo:rustc-cfg=feature=\"oom_with_hook\""); > bootstrap = true; >- } else if std::env::var("MOZ_AUTOMATION").is_ok() && ver >= Version::parse("1.30.0-alpha").unwrap() { >+ } else if std::env::var("MOZ_AUTOMATION").is_ok() >+ && ver >= Version::parse("1.30.0-alpha").unwrap() >+ { > // For the sake of the base-toolchains build we allow building with 1.27, but > // retain this check for newer versions. > panic!("Builds on automation must use a version of rust that supports OOM hooking") > } > > // This is a rather awful thing to do, but we're only doing it on > // versions of rustc that are not going to change the unstable APIs > // we use from under us, all being already released or beta. >diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs >index 55c4e97a4d85..de4d9eae41e4 100644 >--- a/toolkit/library/rust/shared/lib.rs >+++ b/toolkit/library/rust/shared/lib.rs >@@ -1,80 +1,83 @@ > // This Source Code Form is subject to the terms of the Mozilla Public > // License, v. 2.0. If a copy of the MPL was not distributed with this > // file, You can obtain one at http://mozilla.org/MPL/2.0/. > >-#![cfg_attr(feature = "oom_with_global_alloc", >- feature(global_allocator, alloc, alloc_system, allocator_api))] >+#![cfg_attr( >+ feature = "oom_with_global_alloc", >+ feature(global_allocator, alloc, alloc_system, allocator_api) >+)] > #![cfg_attr(feature = "oom_with_hook", feature(alloc_error_hook))] > >-#[cfg(feature="servo")] >+#[cfg(feature = "servo")] > extern crate geckoservo; > >-extern crate mp4parse_capi; >-extern crate nsstring; >-extern crate nserror; >-extern crate xpcom; >-extern crate netwerk_helper; >-extern crate prefs_parser; >-extern crate mozurl; >-#[cfg(feature = "quantum_render")] >-extern crate webrender_bindings; >+#[cfg(feature = "cubeb-remoting")] >+extern crate audioipc_client; >+#[cfg(feature = "cubeb-remoting")] >+extern crate audioipc_server; >+extern crate cosec; > #[cfg(feature = "cubeb_pulse_rust")] > extern crate cubeb_pulse; > extern crate encoding_c; > extern crate encoding_glue; >-#[cfg(feature = "cubeb-remoting")] >-extern crate audioipc_client; >-#[cfg(feature = "cubeb-remoting")] >-extern crate audioipc_server; > extern crate env_logger; >-extern crate u2fhid; > extern crate log; >-extern crate cosec; >+extern crate mozurl; >+extern crate mp4parse_capi; >+extern crate netwerk_helper; >+extern crate nserror; >+extern crate nsstring; >+extern crate prefs_parser; > extern crate rsdparsa_capi; >+extern crate u2fhid; >+#[cfg(feature = "quantum_render")] >+extern crate webrender_bindings; >+extern crate xpcom; > > use std::boxed::Box; > use std::env; > use std::ffi::{CStr, CString}; > use std::os::raw::c_char; > use std::panic; > > extern "C" { > fn gfx_critical_note(msg: *const c_char); > } > > struct GeckoLogger { >- logger: env_logger::Logger >+ logger: env_logger::Logger, > } > > impl GeckoLogger { > fn new() -> GeckoLogger { > let mut builder = env_logger::Builder::new(); >- let default_level = if cfg!(debug_assertions) { "warn" } else { "error" }; >+ let default_level = if cfg!(debug_assertions) { >+ "warn" >+ } else { >+ "error" >+ }; > let logger = match env::var("RUST_LOG") { > Ok(v) => builder.parse(&v).build(), > _ => builder.parse(default_level).build(), > }; > >- GeckoLogger { >- logger >- } >+ GeckoLogger { logger } > } > > fn init() -> Result<(), log::SetLoggerError> { > let gecko_logger = Self::new(); > > log::set_max_level(gecko_logger.logger.filter()); > log::set_boxed_logger(Box::new(gecko_logger)) > } > > fn should_log_to_gfx_critical_note(record: &log::Record) -> bool { >- if record.level() == log::Level::Error && >- record.target().contains("webrender") { >+ if record.level() == log::Level::Error && record.target().contains("webrender") { > true > } else { > false > } > } > > fn maybe_log_to_gfx_critical_note(&self, record: &log::Record) { > if Self::should_log_to_gfx_critical_note(record) { >@@ -92,28 +95,27 @@ impl log::Log for GeckoLogger { > } > > fn log(&self, record: &log::Record) { > // Forward log to gfxCriticalNote, if the log should be in gfx crash log. > self.maybe_log_to_gfx_critical_note(record); > self.logger.log(record); > } > >- fn flush(&self) { } >+ fn flush(&self) {} > } > > #[no_mangle] > pub extern "C" fn GkRust_Init() { > // Initialize logging. > let _ = GeckoLogger::init(); > } > > #[no_mangle] >-pub extern "C" fn GkRust_Shutdown() { >-} >+pub extern "C" fn GkRust_Shutdown() {} > > /// Used to implement `nsIDebug2::RustPanic` for testing purposes. > #[no_mangle] > pub extern "C" fn intentional_panic(message: *const c_char) { > panic!("{}", unsafe { CStr::from_ptr(message) }.to_string_lossy()); > } > > /// Contains the panic message, if set. >@@ -132,19 +134,23 @@ pub extern "C" fn install_rust_panic_hook() { > let default_hook = panic::take_hook(); > panic::set_hook(Box::new(move |info| { > // Try to handle &str/String payloads, which should handle 99% of cases. > let payload = info.payload(); > // We'll hold a raw *const str here, but it will be OK because > // Rust is going to abort the process before the payload could be > // deallocated. > if let Some(s) = payload.downcast_ref::<&str>() { >- unsafe { PANIC_REASON = Some(*s as *const str); } >+ unsafe { >+ PANIC_REASON = Some(*s as *const str); >+ } > } else if let Some(s) = payload.downcast_ref::<String>() { >- unsafe { PANIC_REASON = Some(s.as_str() as *const str); } >+ unsafe { >+ PANIC_REASON = Some(s.as_str() as *const str); >+ } > } else { > // Not the most helpful thing, but seems unlikely to happen > // in practice. > println!("Unhandled panic payload!"); > } > // Fall through to the default hook so we still print the reason and > // backtrace to the console. > default_hook(info); >@@ -217,17 +223,17 @@ mod global_alloc { > } > > #[cfg(feature = "oom_with_global_alloc")] > #[global_allocator] > static HEAP: global_alloc::GeckoHeap = global_alloc::GeckoHeap; > > #[cfg(feature = "oom_with_hook")] > mod oom_hook { >- use std::alloc::{Layout, set_alloc_error_hook}; >+ use std::alloc::{set_alloc_error_hook, Layout}; > > extern "C" { > fn GeckoHandleOOM(size: usize) -> !; > } > > pub fn hook(layout: Layout) { > unsafe { > GeckoHandleOOM(layout.size()); >diff --git a/xpcom/rust/gtest/bench-collections/bench.rs b/xpcom/rust/gtest/bench-collections/bench.rs >index f0ca68ef2d91..632cbd63e399 100644 >--- a/xpcom/rust/gtest/bench-collections/bench.rs >+++ b/xpcom/rust/gtest/bench-collections/bench.rs >@@ -11,80 +11,91 @@ use fnv::FnvHashSet; > use fxhash::FxHashSet; > use std::collections::HashSet; > use std::os::raw::{c_char, c_void}; > use std::slice; > > /// Keep this in sync with Params in Bench.cpp. > #[derive(Debug)] > #[repr(C)] >-pub struct Params >-{ >- config_name: *const c_char, >- num_inserts: usize, >- num_successful_lookups: usize, >- num_failing_lookups: usize, >- num_iterations: usize, >- remove_inserts: bool, >+pub struct Params { >+ config_name: *const c_char, >+ num_inserts: usize, >+ num_successful_lookups: usize, >+ num_failing_lookups: usize, >+ num_iterations: usize, >+ remove_inserts: bool, > } > > #[no_mangle] >-pub extern "C" fn Bench_Rust_HashSet(params: *const Params, vals: *const *const c_void, >- len: usize) { >+pub extern "C" fn Bench_Rust_HashSet( >+ params: *const Params, >+ vals: *const *const c_void, >+ len: usize, >+) { > let hs: HashSet<_> = std::collections::HashSet::default(); > Bench_Rust(hs, params, vals, len); > } > > #[no_mangle] >-pub extern "C" fn Bench_Rust_FnvHashSet(params: *const Params, vals: *const *const c_void, >- len: usize) { >+pub extern "C" fn Bench_Rust_FnvHashSet( >+ params: *const Params, >+ vals: *const *const c_void, >+ len: usize, >+) { > let hs = FnvHashSet::default(); > Bench_Rust(hs, params, vals, len); > } > > #[no_mangle] >-pub extern "C" fn Bench_Rust_FxHashSet(params: *const Params, vals: *const *const c_void, >- len: usize) { >+pub extern "C" fn Bench_Rust_FxHashSet( >+ params: *const Params, >+ vals: *const *const c_void, >+ len: usize, >+) { > let hs = FxHashSet::default(); > Bench_Rust(hs, params, vals, len); > } > > // Keep this in sync with all the other Bench_*() functions. >-fn Bench_Rust<H: std::hash::BuildHasher>(mut hs: HashSet<*const c_void, H>, params: *const Params, >- vals: *const *const c_void, len: usize) { >+fn Bench_Rust<H: std::hash::BuildHasher>( >+ mut hs: HashSet<*const c_void, H>, >+ params: *const Params, >+ vals: *const *const c_void, >+ len: usize, >+) { > let params = unsafe { &*params }; > let vals = unsafe { slice::from_raw_parts(vals, len) }; > > for j in 0..params.num_inserts { > hs.insert(vals[j]); > } > > for _i in 0..params.num_successful_lookups { > for j in 0..params.num_inserts { > assert!(hs.contains(&vals[j])); > } > } > > for _i in 0..params.num_failing_lookups { >- for j in params.num_inserts..params.num_inserts*2 { >+ for j in params.num_inserts..params.num_inserts * 2 { > assert!(!hs.contains(&vals[j])); > } > } > > for _i in 0..params.num_iterations { >- let mut n = 0; >- for _ in hs.iter() { >- n += 1; >- } >- assert!(params.num_inserts == n); >- assert!(hs.len() == n); >+ let mut n = 0; >+ for _ in hs.iter() { >+ n += 1; >+ } >+ assert!(params.num_inserts == n); >+ assert!(hs.len() == n); > } > > if params.remove_inserts { > for j in 0..params.num_inserts { > assert!(hs.remove(&vals[j])); > } > assert!(hs.len() == 0); > } else { > assert!(hs.len() == params.num_inserts); > } > } >- >diff --git a/xpcom/rust/gtest/nsstring/test.rs b/xpcom/rust/gtest/nsstring/test.rs >index 4ab7f46ff3c0..8e148ce9dc98 100644 >--- a/xpcom/rust/gtest/nsstring/test.rs >+++ b/xpcom/rust/gtest/nsstring/test.rs >@@ -1,74 +1,79 @@ > #![allow(non_snake_case)] > > extern crate nsstring; > >-use std::fmt::Write; >+use nsstring::*; > use std::ffi::CString; >+use std::fmt::Write; > use std::os::raw::c_char; >-use nsstring::*; > > fn nonfatal_fail(msg: String) { > extern "C" { > fn GTest_ExpectFailure(message: *const c_char); > } > unsafe { > GTest_ExpectFailure(CString::new(msg).unwrap().as_ptr()); > } > } > > /// This macro checks if the two arguments are equal, and causes a non-fatal > /// GTest test failure if they are not. > macro_rules! expect_eq { > ($x:expr, $y:expr) => { > match (&$x, &$y) { > (x, y) => if *x != *y { >- nonfatal_fail(format!("check failed: (`{:?}` == `{:?}`) at {}:{}", >- x, y, file!(), line!())) >- } >+ nonfatal_fail(format!( >+ "check failed: (`{:?}` == `{:?}`) at {}:{}", >+ x, >+ y, >+ file!(), >+ line!() >+ )) >+ }, > } >- } >+ }; > } > > #[no_mangle] >-pub extern fn Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString) { >+pub extern "C" fn Rust_StringFromCpp(cs: *const nsACString, s: *const nsAString) { > unsafe { > expect_eq!(&*cs, "Hello, World!"); > expect_eq!(&*s, "Hello, World!"); > } > } > > #[no_mangle] >-pub extern fn Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString) { >+pub extern "C" fn Rust_AssignFromRust(cs: *mut nsACString, s: *mut nsAString) { > unsafe { > (*cs).assign(&nsCString::from("Hello, World!")); > expect_eq!(&*cs, "Hello, World!"); > (*s).assign(&nsString::from("Hello, World!")); > expect_eq!(&*s, "Hello, World!"); > } > } > > extern "C" { > fn Cpp_AssignFromCpp(cs: *mut nsACString, s: *mut nsAString); > } > > #[no_mangle] >-pub extern fn Rust_AssignFromCpp() { >+pub extern "C" fn Rust_AssignFromCpp() { > let mut cs = nsCString::new(); > let mut s = nsString::new(); > unsafe { > Cpp_AssignFromCpp(&mut *cs, &mut *s); > } > expect_eq!(cs, "Hello, World!"); > expect_eq!(s, "Hello, World!"); > } > > #[no_mangle] >-pub extern fn Rust_StringWrite() { >+pub extern "C" fn Rust_StringWrite() { > let mut cs = nsCString::new(); > let mut s = nsString::new(); > > write!(s, "a").unwrap(); > write!(cs, "a").unwrap(); > expect_eq!(s, "a"); > expect_eq!(cs, "a"); > write!(s, "bc").unwrap(); >@@ -77,24 +82,29 @@ pub extern fn Rust_StringWrite() { > expect_eq!(cs, "abc"); > write!(s, "{}", 123).unwrap(); > write!(cs, "{}", 123).unwrap(); > expect_eq!(s, "abc123"); > expect_eq!(cs, "abc123"); > } > > #[no_mangle] >-pub extern fn Rust_FromEmptyRustString() { >+pub extern "C" fn Rust_FromEmptyRustString() { > let mut test = nsString::from("Blah"); > test.assign_utf8(&nsCString::from(String::new())); > assert!(test.is_empty()); > } > > #[no_mangle] >-pub extern fn Rust_WriteToBufferFromRust(cs: *mut nsACString, s: *mut nsAString, fallible_cs: *mut nsACString, fallible_s: *mut nsAString) { >+pub extern "C" fn Rust_WriteToBufferFromRust( >+ cs: *mut nsACString, >+ s: *mut nsAString, >+ fallible_cs: *mut nsACString, >+ fallible_s: *mut nsAString, >+) { > unsafe { > let cs_buf = (*cs).to_mut(); > let s_buf = (*s).to_mut(); > let fallible_cs_buf = (*fallible_cs).fallible_to_mut().unwrap(); > let fallible_s_buf = (*fallible_s).fallible_to_mut().unwrap(); > > cs_buf[0] = b'A'; > cs_buf[1] = b'B'; >diff --git a/xpcom/rust/gtest/xpcom/test.rs b/xpcom/rust/gtest/xpcom/test.rs >index f2931499524f..a8ee9b18d2f6 100644 >--- a/xpcom/rust/gtest/xpcom/test.rs >+++ b/xpcom/rust/gtest/xpcom/test.rs >@@ -4,69 +4,79 @@ > > #![allow(non_snake_case)] > > #[macro_use] > extern crate xpcom; > > extern crate nserror; > >+use nserror::{nsresult, NsresultExt, NS_OK}; >+use std::ffi::{CStr, CString}; > use std::os::raw::c_char; > use std::ptr; >-use std::ffi::{CStr, CString}; > use xpcom::interfaces; >-use nserror::{NsresultExt, nsresult, NS_OK}; > > #[no_mangle] >-pub unsafe extern fn Rust_ObserveFromRust() -> *const interfaces::nsIObserverService { >+pub unsafe extern "C" fn Rust_ObserveFromRust() -> *const interfaces::nsIObserverService { > let obssvc = xpcom::services::get_ObserverService().unwrap(); > > // Define an observer > #[derive(xpcom)] > #[xpimplements(nsIObserver)] > #[refcnt = "nonatomic"] > struct InitObserver { >- run: *mut bool >+ run: *mut bool, > } > impl Observer { > unsafe fn Observe( > &self, > _subject: *const interfaces::nsISupports, > topic: *const c_char, >- _data: *const i16 >+ _data: *const i16, > ) -> nsresult { > *self.run = true; > assert!(CStr::from_ptr(topic).to_str() == Ok("test-rust-observe")); > NS_OK > } > } > > let topic = CString::new("test-rust-observe").unwrap(); > > let mut run = false; >- let observer = Observer::allocate(InitObserver{ run: &mut run }); >- let rv = obssvc.AddObserver(observer.coerce::<interfaces::nsIObserver>(), topic.as_ptr(), false); >+ let observer = Observer::allocate(InitObserver { run: &mut run }); >+ let rv = obssvc.AddObserver( >+ observer.coerce::<interfaces::nsIObserver>(), >+ topic.as_ptr(), >+ false, >+ ); > assert!(rv.succeeded()); > > let rv = obssvc.NotifyObservers(ptr::null(), topic.as_ptr(), ptr::null()); > assert!(rv.succeeded()); > assert!(run, "The observer should have been run!"); > > let rv = obssvc.RemoveObserver(observer.coerce::<interfaces::nsIObserver>(), topic.as_ptr()); > assert!(rv.succeeded()); > >- assert!(observer.coerce::<interfaces::nsISupports>() as *const _== >- &*observer.query_interface::<interfaces::nsISupports>().unwrap() as *const _); >+ assert!( >+ observer.coerce::<interfaces::nsISupports>() as *const _ == &*observer >+ .query_interface::<interfaces::nsISupports>() >+ .unwrap() >+ as *const _ >+ ); > > &*obssvc > } > > #[no_mangle] >-pub unsafe extern fn Rust_ImplementRunnableInRust(it_worked: *mut bool, >- runnable: *mut *const interfaces::nsIRunnable) { >+pub unsafe extern "C" fn Rust_ImplementRunnableInRust( >+ it_worked: *mut bool, >+ runnable: *mut *const interfaces::nsIRunnable, >+) { > // Define a type which implements nsIRunnable in rust. > #[derive(xpcom)] > #[xpimplements(nsIRunnable)] > #[refcnt = "atomic"] > struct InitMyRunnable { > it_worked: *mut bool, > } > >@@ -74,12 +84,15 @@ pub unsafe extern fn Rust_ImplementRunnableInRust(it_worked: *mut bool, > unsafe fn Run(&self) -> nsresult { > *self.it_worked = true; > NS_OK > } > } > > // Create my runnable type, and forget it into the outparameter! > let my_runnable = MyRunnable::allocate(InitMyRunnable { >- it_worked: it_worked >+ it_worked: it_worked, > }); >- my_runnable.query_interface::<interfaces::nsIRunnable>().unwrap().forget(&mut *runnable); >+ my_runnable >+ .query_interface::<interfaces::nsIRunnable>() >+ .unwrap() >+ .forget(&mut *runnable); > } >diff --git a/xpcom/rust/nserror/src/lib.rs b/xpcom/rust/nserror/src/lib.rs >index 94c962962de1..9231b35f8fd4 100644 >--- a/xpcom/rust/nserror/src/lib.rs >+++ b/xpcom/rust/nserror/src/lib.rs >@@ -1,11 +1,11 @@ > extern crate nsstring; > >-use nsstring::{nsCString, nsACString}; >+use nsstring::{nsACString, nsCString}; > > /// The type of errors in gecko. This type is currently a type alias, rather > /// than a newtype, in order to conform to the C ABI. In future versions of rust > /// which support RFC #1758 or similar we may be able to use > /// `#[repr(transparent)]` to get a better API for using nsresult. > /// > /// The most unfortunate thing about this current implementation is that `u32` > /// and `nsresult` unify. >diff --git a/xpcom/rust/xpcom/src/base.rs b/xpcom/rust/xpcom/src/base.rs >index c8104755b99d..9d13cdc95d8d 100644 >--- a/xpcom/rust/xpcom/src/base.rs >+++ b/xpcom/rust/xpcom/src/base.rs >@@ -1,19 +1,15 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > >-use { >- RefCounted, >- RefPtr, >- GetterAddrefs >-}; > use interfaces::nsISupports; > use nserror::NsresultExt; >+use {GetterAddrefs, RefCounted, RefPtr}; > > #[repr(C)] > #[derive(Copy, Clone, Eq, PartialEq)] > /// A "unique identifier". This is modeled after OSF DCE UUIDs. > pub struct nsID(pub u32, pub u16, pub u16, pub [u8; 8]); > > /// Interface IDs > pub type nsIID = nsID; >@@ -21,28 +17,28 @@ pub type nsIID = nsID; > pub type nsCID = nsID; > > /// A type which implements XpCom must follow the following rules: > /// > /// * It must be a legal XPCOM interface. > /// * The result of a QueryInterface or similar call, passing IID, must return a > /// valid reference to an object of the given type. > /// * It must be valid to cast a &self reference to a &nsISupports reference. >-pub unsafe trait XpCom : RefCounted { >+pub unsafe trait XpCom: RefCounted { > const IID: nsIID; > > /// Perform a QueryInterface call on this object, attempting to dynamically > /// cast it to the requested interface type. Returns Some(RefPtr<T>) if the > /// cast succeeded, and None otherwise. > fn query_interface<T: XpCom>(&self) -> Option<RefPtr<T>> { > let mut ga = GetterAddrefs::<T>::new(); > unsafe { >- if (*(self as *const Self as *const nsISupports)).QueryInterface( >- &T::IID, >- ga.void_ptr(), >- ).succeeded() { >+ if (*(self as *const Self as *const nsISupports)) >+ .QueryInterface(&T::IID, ga.void_ptr()) >+ .succeeded() >+ { > ga.refptr() > } else { > None > } > } > } > } >diff --git a/xpcom/rust/xpcom/src/interfaces/idl.rs b/xpcom/rust/xpcom/src/interfaces/idl.rs >index 6065c3b3f4a3..b367b82a31e6 100644 >--- a/xpcom/rust/xpcom/src/interfaces/idl.rs >+++ b/xpcom/rust/xpcom/src/interfaces/idl.rs >@@ -1,12 +1,12 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > #![allow(bad_style)] > >-use *; > use interfaces::*; >+use *; > > // NOTE: This file contains a series of `include!()` invocations, defining all > // idl interfaces directly within this module. > include!(concat!(env!("MOZ_TOPOBJDIR"), "/dist/xpcrs/rt/all.rs")); >diff --git a/xpcom/rust/xpcom/src/interfaces/nonidl.rs b/xpcom/rust/xpcom/src/interfaces/nonidl.rs >index f3050eb931a5..15f4a93dac12 100644 >--- a/xpcom/rust/xpcom/src/interfaces/nonidl.rs >+++ b/xpcom/rust/xpcom/src/interfaces/nonidl.rs >@@ -36,75 +36,145 @@ macro_rules! nonidl { > self.Release(); > } > } > > impl ::std::ops::Deref for $name { > type Target = $crate::interfaces::nsISupports; > #[inline] > fn deref(&self) -> &$crate::interfaces::nsISupports { >- unsafe { >- ::std::mem::transmute(self) >- } >+ unsafe { ::std::mem::transmute(self) } > } > } >- } >+ }; > } > > // Must be kept in sync with nsIDocument.h >-nonidl!(nsIDocument, >- nsID(0xce1f7627, 0x7109, 0x4977, >- [0xba, 0x77, 0x49, 0x0f, 0xfd, 0xe0, 0x7a, 0xaa])); >+nonidl!( >+ nsIDocument, >+ nsID( >+ 0xce1f7627, >+ 0x7109, >+ 0x4977, >+ [0xba, 0x77, 0x49, 0x0f, 0xfd, 0xe0, 0x7a, 0xaa] >+ ) >+); > > // Must be kept in sync with nsINode.h >-nonidl!(nsINode, >- nsID(0x70ba4547, 0x7699, 0x44fc, >- [0xb3, 0x20, 0x52, 0xdb, 0xe3, 0xd1, 0xf9, 0x0a])); >+nonidl!( >+ nsINode, >+ nsID( >+ 0x70ba4547, >+ 0x7699, >+ 0x44fc, >+ [0xb3, 0x20, 0x52, 0xdb, 0xe3, 0xd1, 0xf9, 0x0a] >+ ) >+); > > // Must be kept in sync with nsIContent.h >-nonidl!(nsIContent, >- nsID(0x8e1bab9d, 0x8815, 0x4d2c, >- [0xa2, 0x4d, 0x7a, 0xba, 0x52, 0x39, 0xdc, 0x22])); >+nonidl!( >+ nsIContent, >+ nsID( >+ 0x8e1bab9d, >+ 0x8815, >+ 0x4d2c, >+ [0xa2, 0x4d, 0x7a, 0xba, 0x52, 0x39, 0xdc, 0x22] >+ ) >+); > > // Must be kept in sync with nsIConsoleReportCollector.h >-nonidl!(nsIConsoleReportCollector, >- nsID(0xdd98a481, 0xd2c4, 0x4203, >- [0x8d, 0xfa, 0x85, 0xbf, 0xd7, 0xdc, 0xd7, 0x05])); >+nonidl!( >+ nsIConsoleReportCollector, >+ nsID( >+ 0xdd98a481, >+ 0xd2c4, >+ 0x4203, >+ [0x8d, 0xfa, 0x85, 0xbf, 0xd7, 0xdc, 0xd7, 0x05] >+ ) >+); > > // Must be kept in sync with nsIGlobalObject.h >-nonidl!(nsIGlobalObject, >- nsID(0x11afa8be, 0xd997, 0x4e07, >- [0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f])); >+nonidl!( >+ nsIGlobalObject, >+ nsID( >+ 0x11afa8be, >+ 0xd997, >+ 0x4e07, >+ [0xa6, 0xa3, 0x6f, 0x87, 0x2e, 0xc3, 0xee, 0x7f] >+ ) >+); > > // Must be kept in sync with nsIScriptElement.h >-nonidl!(nsIScriptElement, >- nsID(0xe60fca9b, 0x1b96, 0x4e4e, >- [0xa9, 0xb4, 0xdc, 0x98, 0x4f, 0x88, 0x3f, 0x9c])); >+nonidl!( >+ nsIScriptElement, >+ nsID( >+ 0xe60fca9b, >+ 0x1b96, >+ 0x4e4e, >+ [0xa9, 0xb4, 0xdc, 0x98, 0x4f, 0x88, 0x3f, 0x9c] >+ ) >+); > > // Must be kept in sync with nsPIDOMWindow.h >-nonidl!(nsPIDOMWindowOuter, >- nsID(0x769693d4, 0xb009, 0x4fe2, >- [0xaf, 0x18, 0x7d, 0xc8, 0xdf, 0x74, 0x96, 0xdf])); >+nonidl!( >+ nsPIDOMWindowOuter, >+ nsID( >+ 0x769693d4, >+ 0xb009, >+ 0x4fe2, >+ [0xaf, 0x18, 0x7d, 0xc8, 0xdf, 0x74, 0x96, 0xdf] >+ ) >+); > > // Must be kept in sync with nsPIDOMWindow.h >-nonidl!(nsPIDOMWindowInner, >- nsID(0x775dabc9, 0x8f43, 0x4277, >- [0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb])); >+nonidl!( >+ nsPIDOMWindowInner, >+ nsID( >+ 0x775dabc9, >+ 0x8f43, >+ 0x4277, >+ [0x9a, 0xdb, 0xf1, 0x99, 0x0d, 0x77, 0xcf, 0xfb] >+ ) >+); > > // Must be kept in sync with nsIScriptContext.h >-nonidl!(nsIScriptContext, >- nsID(0x54cbe9cf, 0x7282, 0x421a, >- [0x91, 0x6f, 0xd0, 0x70, 0x73, 0xde, 0xb8, 0xc0])); >+nonidl!( >+ nsIScriptContext, >+ nsID( >+ 0x54cbe9cf, >+ 0x7282, >+ 0x421a, >+ [0x91, 0x6f, 0xd0, 0x70, 0x73, 0xde, 0xb8, 0xc0] >+ ) >+); > > // Must be kept in sync with nsIScriptGlobalObject.h >-nonidl!(nsIScriptGlobalObject, >- nsID(0x876f83bd, 0x6314, 0x460a, >- [0xa0, 0x45, 0x1c, 0x8f, 0x46, 0x2f, 0xb8, 0xe1])); >+nonidl!( >+ nsIScriptGlobalObject, >+ nsID( >+ 0x876f83bd, >+ 0x6314, >+ 0x460a, >+ [0xa0, 0x45, 0x1c, 0x8f, 0x46, 0x2f, 0xb8, 0xe1] >+ ) >+); > > // Must be kept in sync with nsIScrollObserver.h >-nonidl!(nsIScrollObserver, >- nsID(0xaa5026eb, 0x2f88, 0x4026, >- [0xa4, 0x6b, 0xf4, 0x59, 0x6b, 0x4e, 0xdf, 0x00])); >+nonidl!( >+ nsIScrollObserver, >+ nsID( >+ 0xaa5026eb, >+ 0x2f88, >+ 0x4026, >+ [0xa4, 0x6b, 0xf4, 0x59, 0x6b, 0x4e, 0xdf, 0x00] >+ ) >+); > > // Must be kept in sync with nsIWidget.h >-nonidl!(nsIWidget, >- nsID(0x06396bf6, 0x2dd8, 0x45e5, >- [0xac, 0x45, 0x75, 0x26, 0x53, 0xb1, 0xc9, 0x80])); >+nonidl!( >+ nsIWidget, >+ nsID( >+ 0x06396bf6, >+ 0x2dd8, >+ 0x45e5, >+ [0xac, 0x45, 0x75, 0x26, 0x53, 0xb1, 0xc9, 0x80] >+ ) >+); >diff --git a/xpcom/rust/xpcom/src/lib.rs b/xpcom/rust/xpcom/src/lib.rs >index c75521780b04..f04463630a49 100644 >--- a/xpcom/rust/xpcom/src/lib.rs >+++ b/xpcom/rust/xpcom/src/lib.rs >@@ -7,18 +7,18 @@ > //! > //! For documentation on how to implement XPCOM methods, see the documentation > //! for the [`xpcom_macros`](../xpcom_macros/index.html) crate. > > #![allow(non_snake_case)] > #![allow(non_camel_case_types)] > > extern crate libc; >-extern crate nsstring; > extern crate nserror; >+extern crate nsstring; > > // re-export the xpcom_macros macro > #[macro_use] > #[allow(unused_imports)] > extern crate xpcom_macros; > #[doc(hidden)] > pub use xpcom_macros::*; > >diff --git a/xpcom/rust/xpcom/src/reexports.rs b/xpcom/rust/xpcom/src/reexports.rs >index 623e8a44580e..df6d99905253 100644 >--- a/xpcom/rust/xpcom/src/reexports.rs >+++ b/xpcom/rust/xpcom/src/reexports.rs >@@ -2,17 +2,16 @@ > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > > /// The automatically generated code from `xpcom_macros` depends on some types > /// which are defined in other libraries which `xpcom` depends on, but which may > /// not be `extern crate`-ed into the crate the macros are expanded into. This > /// module re-exports those types from `xpcom` so that they can be used from the > /// macro. >- > // re-export libc so it can be used by the procedural macro. > pub extern crate libc; > > pub use nsstring::{nsACString, nsAString, nsCString, nsString}; > > pub use nserror::{nsresult, NsresultExt, NS_ERROR_NO_INTERFACE, NS_OK}; > > pub use std::ops::Deref; >diff --git a/xpcom/rust/xpcom/src/refptr.rs b/xpcom/rust/xpcom/src/refptr.rs >index 3b1909bbd5e1..b07c432920f0 100644 >--- a/xpcom/rust/xpcom/src/refptr.rs >+++ b/xpcom/rust/xpcom/src/refptr.rs >@@ -1,20 +1,20 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > >+use std::cell::Cell; >+use std::marker::PhantomData; > use std::mem; >-use std::ptr; > use std::ops::Deref; >-use std::marker::PhantomData; >-use std::cell::Cell; >+use std::ptr; > use std::sync::atomic::{self, AtomicUsize, Ordering}; > >-use nserror::{NsresultExt, nsresult, NS_OK}; >+use nserror::{nsresult, NsresultExt, NS_OK}; > > use libc; > > use interfaces::nsrefcnt; > > /// A trait representing a type which can be reference counted invasively. > /// The object is responsible for freeing its backing memory when its > /// reference count reaches 0. >@@ -35,17 +35,17 @@ pub struct RefPtr<T: RefCounted + 'static> { > // I believe that this is "safe enough", as this module is private and > // no other module can read this reference. > _ptr: &'static T, > // As we aren't using Shared<T>, we need to add this phantomdata to > // prevent unsoundness in dropck > _marker: PhantomData<T>, > } > >-impl <T: RefCounted + 'static> RefPtr<T> { >+impl<T: RefCounted + 'static> RefPtr<T> { > /// Construct a new RefPtr from a reference to the refcounted object. > #[inline] > pub fn new(p: &T) -> RefPtr<T> { > unsafe { > p.addref(); > RefPtr { > _ptr: mem::transmute(p), > _marker: PhantomData, >@@ -81,51 +81,51 @@ impl <T: RefCounted + 'static> RefPtr<T> { > /// Write this RefPtr's value into an outparameter. > #[inline] > pub fn forget(self, into: &mut *const T) { > *into = &*self; > mem::forget(self); > } > } > >-impl <T: RefCounted + 'static> Deref for RefPtr<T> { >+impl<T: RefCounted + 'static> Deref for RefPtr<T> { > type Target = T; > #[inline] > fn deref(&self) -> &T { > self._ptr > } > } > >-impl <T: RefCounted + 'static> Drop for RefPtr<T> { >+impl<T: RefCounted + 'static> Drop for RefPtr<T> { > #[inline] > fn drop(&mut self) { > unsafe { > self._ptr.release(); > } > } > } > >-impl <T: RefCounted + 'static> Clone for RefPtr<T> { >+impl<T: RefCounted + 'static> Clone for RefPtr<T> { > #[inline] > fn clone(&self) -> RefPtr<T> { > RefPtr::new(self) > } > } > > /// A helper struct for constructing `RefPtr<T>` from raw pointer outparameters. > /// Holds a `*const T` internally which will be released if non null when > /// destructed, and can be easily transformed into an `Option<RefPtr<T>>`. > /// > /// It many cases it may be easier to use the `getter_addrefs` method. > pub struct GetterAddrefs<T: RefCounted + 'static> { > _ptr: *const T, > _marker: PhantomData<T>, > } > >-impl <T: RefCounted + 'static> GetterAddrefs<T> { >+impl<T: RefCounted + 'static> GetterAddrefs<T> { > /// Create a `GetterAddrefs`, initializing it with the null pointer. > #[inline] > pub fn new() -> GetterAddrefs<T> { > GetterAddrefs { > _ptr: ptr::null(), > _marker: PhantomData, > } > } >@@ -149,23 +149,21 @@ impl <T: RefCounted + 'static> GetterAddrefs<T> { > /// Transform this `GetterAddrefs` into an `Option<RefPtr<T>>`, without > /// performing any addrefs or releases. > #[inline] > pub fn refptr(self) -> Option<RefPtr<T>> { > let p = self._ptr; > // Don't run the destructor because we don't want to release the stored > // pointer. > mem::forget(self); >- unsafe { >- RefPtr::from_raw_dont_addref(p) >- } >+ unsafe { RefPtr::from_raw_dont_addref(p) } > } > } > >-impl <T: RefCounted + 'static> Drop for GetterAddrefs<T> { >+impl<T: RefCounted + 'static> Drop for GetterAddrefs<T> { > #[inline] > fn drop(&mut self) { > if !self._ptr.is_null() { > unsafe { > (*self._ptr).release(); > } > } > } >@@ -185,17 +183,18 @@ impl <T: RefCounted + 'static> Drop for GetterAddrefs<T> { > /// # Usage > /// > /// ``` > /// let x: Result<RefPtr<T>, nsresult> = > /// getter_addrefs(|p| iosvc.NewURI(uri, ptr::null(), ptr::null(), p)); > /// ``` > #[inline] > pub fn getter_addrefs<T: RefCounted, F>(f: F) -> Result<RefPtr<T>, nsresult> >- where F: FnOnce(*mut *const T) -> nsresult >+where >+ F: FnOnce(*mut *const T) -> nsresult, > { > let mut ga = GetterAddrefs::<T>::new(); > let rv = f(unsafe { ga.ptr() }); > if rv.failed() { > return Err(rv); > } > ga.refptr().ok_or(NS_OK) > } >diff --git a/xpcom/rust/xpcom/src/statics.rs b/xpcom/rust/xpcom/src/statics.rs >index 6565035db9af..7af100f9b9c3 100644 >--- a/xpcom/rust/xpcom/src/statics.rs >+++ b/xpcom/rust/xpcom/src/statics.rs >@@ -1,100 +1,83 @@ > /* This Source Code Form is subject to the terms of the Mozilla Public > * License, v. 2.0. If a copy of the MPL was not distributed with this > * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ > >+use nserror::NsresultExt; > use std::ffi::CStr; > use std::ptr; >-use nserror::NsresultExt; >-use { >- RefPtr, >- GetterAddrefs, >- XpCom, >-}; >+use {GetterAddrefs, RefPtr, XpCom}; > >-use interfaces::{ >- nsIComponentManager, >- nsIServiceManager, >- nsIComponentRegistrar, >-}; >+use interfaces::{nsIComponentManager, nsIComponentRegistrar, nsIServiceManager}; > > macro_rules! try_opt { > ($e: expr) => { > match $e { > Some(x) => x, > None => return None, > } >- } >+ }; > } > > /// Get a reference to the global `nsIComponentManager`. > /// > /// Can return `None` during shutdown. > #[inline] > pub fn component_manager() -> Option<RefPtr<nsIComponentManager>> { >- unsafe { >- RefPtr::from_raw(Gecko_GetComponentManager()) >- } >+ unsafe { RefPtr::from_raw(Gecko_GetComponentManager()) } > } > > /// Get a reference to the global `nsIServiceManager`. > /// > /// Can return `None` during shutdown. > #[inline] > pub fn service_manager() -> Option<RefPtr<nsIServiceManager>> { >- unsafe { >- RefPtr::from_raw(Gecko_GetServiceManager()) >- } >+ unsafe { RefPtr::from_raw(Gecko_GetServiceManager()) } > } > > /// Get a reference to the global `nsIComponentRegistrar` > /// > /// Can return `None` during shutdown. > #[inline] > pub fn component_registrar() -> Option<RefPtr<nsIComponentRegistrar>> { >- unsafe { >- RefPtr::from_raw(Gecko_GetComponentRegistrar()) >- } >+ unsafe { RefPtr::from_raw(Gecko_GetComponentRegistrar()) } > } > > /// Helper for calling `nsIComponentManager::CreateInstanceByContractID` on the > /// global `nsIComponentRegistrar`. > /// > /// This method is similar to `do_CreateInstance` in C++. > #[inline] > pub fn create_instance<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> { > unsafe { > let mut ga = GetterAddrefs::<T>::new(); >- if try_opt!(component_manager()).CreateInstanceByContractID( >- id.as_ptr(), >- ptr::null(), >- &T::IID, >- ga.void_ptr(), >- ).succeeded() { >+ if try_opt!(component_manager()) >+ .CreateInstanceByContractID(id.as_ptr(), ptr::null(), &T::IID, ga.void_ptr()) >+ .succeeded() >+ { > ga.refptr() > } else { > None > } > } > } > > /// Helper for calling `nsIServiceManager::GetServiceByContractID` on the global > /// `nsIServiceManager`. > /// > /// This method is similar to `do_GetService` in C++. > #[inline] > pub fn get_service<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> { > unsafe { > let mut ga = GetterAddrefs::<T>::new(); >- if try_opt!(service_manager()).GetServiceByContractID( >- id.as_ptr(), >- &T::IID, >- ga.void_ptr() >- ).succeeded() { >+ if try_opt!(service_manager()) >+ .GetServiceByContractID(id.as_ptr(), &T::IID, ga.void_ptr()) >+ .succeeded() >+ { > ga.refptr() > } else { > None > } > } > } > > extern "C" { >diff --git a/xpcom/rust/xpcom/xpcom_macros/src/lib.rs b/xpcom/rust/xpcom/xpcom_macros/src/lib.rs >index 260d4ca64b18..af71a4e99938 100644 >--- a/xpcom/rust/xpcom/xpcom_macros/src/lib.rs >+++ b/xpcom/rust/xpcom/xpcom_macros/src/lib.rs >@@ -121,17 +121,17 @@ > //! > //! [`xpcom`]: ../xpcom/index.html > //! [`nsIRunnable`]: ../xpcom/struct.nsIRunnable.html > //! [`RefCounted`]: ../xpcom/struct.RefCounted.html > //! [`RefPtr`]: ../xpcom/struct.RefPtr.html > > // NOTE: We use some really big quote! invocations, so we need a high recursion > // limit. >-#![recursion_limit="256"] >+#![recursion_limit = "256"] > > #[macro_use] > extern crate quote; > > #[macro_use] > extern crate syn; > > extern crate proc_macro; >@@ -174,19 +174,21 @@ struct Interface { > name: &'static str, > base: Option<&'static str>, > methods: Result<&'static [Method], &'static str>, > } > > impl Interface { > fn base(&self) -> Result<Option<&'static Interface>, Box<Error>> { > Ok(if let Some(base) = self.base { >- Some(*IFACES.get(base).ok_or_else( >- || format!("Base interface {} does not exist", base) >- )?) >+ Some( >+ *IFACES >+ .get(base) >+ .ok_or_else(|| format!("Base interface {} does not exist", base))?, >+ ) > } else { > None > }) > } > } > > lazy_static! { > /// This item contains the information generated by the procedural macro in >@@ -261,64 +263,73 @@ fn get_bases(attrs: &[Attribute]) -> Result<Vec<&'static Interface>, Box<Error>> > continue; > } > > for item in &attr.nested { > if let NestedMeta::Meta(Meta::Word(ref iface)) = *item { > if let Some(&iface) = IFACES.get(iface.as_ref()) { > inherits.push(iface); > } else { >- Err(format!("Unexpected invalid base interface `{}` in \ >- #[xpimplements(..)]", iface))? >+ Err(format!( >+ "Unexpected invalid base interface `{}` in \ >+ #[xpimplements(..)]", >+ iface >+ ))? > } > } else { > Err("Unexpected non-identifier in #[xpimplements(..)]")? > } > } > } > } > Ok(inherits) > } > > /// Extract the fields list from the input struct. > fn get_fields(di: &DeriveInput) -> Result<&Punctuated<Field, Token![,]>, Box<Error>> { > match di.data { > Data::Struct(DataStruct { >- fields: Fields::Named(ref named), .. >+ fields: Fields::Named(ref named), >+ .. > }) => Ok(&named.named), > _ => Err("The initializer struct must be a standard \ >- named value struct definition".into()) >+ named value struct definition" >+ .into()), > } > } > > /// Takes the `Init*` struct in, and generates a `DeriveInput` for the "real" struct. >-fn gen_real_struct(init: &DeriveInput, bases: &[&Interface], refcnt_ty: RefcntKind) -> Result<DeriveInput, Box<Error>> { >+fn gen_real_struct( >+ init: &DeriveInput, >+ bases: &[&Interface], >+ refcnt_ty: RefcntKind, >+) -> Result<DeriveInput, Box<Error>> { > // Determine the name for the real struct based on the name of the > // initializer struct's name. > if !init.ident.as_ref().starts_with("Init") { > Err("The target struct's name must begin with Init")? > } > let name: Ident = init.ident.as_ref()[4..].into(); > let vis = &init.vis; > > let bases = bases.iter().map(|base| { > let ident = Ident::from(format!("__base_{}", base.name)); > let vtable = Ident::from(format!("{}VTable", base.name)); > quote!(#ident : *const xpcom::interfaces::#vtable) >- }); >+ }); > > let fields = get_fields(init)?; > Ok(parse_quote! { >- #[repr(C)] >- #vis struct #name { >- #(#bases,)* >- __refcnt: #refcnt_ty, >- #fields >- } >- }) >+ #[repr(C)] >+ #vis struct #name { >+ #(#bases,)* >+ __refcnt: #refcnt_ty, >+ #fields >+ } >+ }) > } > > /// Generates the `extern "system"` methods which are actually included in the > /// VTable for the given interface. > /// > /// These methods attempt to invoke the `recover_self` method to translate from > /// the passed-in raw pointer to the actual `&self` value, and it is expected to > /// be in scope. >@@ -326,19 +337,23 @@ fn gen_vtable_methods(iface: &Interface) -> Result<Tokens, Box<Error>> { > let base_ty = Ident::from(iface.name); > > let base_methods = if let Some(base) = iface.base()? { > gen_vtable_methods(base)? > } else { > quote!{} > }; > >- let methods = iface.methods >- .map_err(|reason| format!("Interface {} cannot be implemented in rust \ >- because {} is not supported yet", iface.name, reason))?; >+ let methods = iface.methods.map_err(|reason| { >+ format!( >+ "Interface {} cannot be implemented in rust \ >+ because {} is not supported yet", >+ iface.name, reason >+ ) >+ })?; > > let mut method_defs = Vec::new(); > for method in methods { > let name = Ident::from(method.name); > let ret = syn::parse_str::<Type>(method.ret)?; > > let mut params = Vec::new(); > let mut args = Vec::new(); >@@ -364,33 +379,39 @@ fn gen_vtable_methods(iface: &Interface) -> Result<Tokens, Box<Error>> { > }) > } > > /// Generates the VTable for a given base interface. This assumes that the > /// implementations of each of the `extern "system"` methods are in scope. > fn gen_inner_vtable(iface: &Interface) -> Result<Tokens, Box<Error>> { > let vtable_ty = Ident::from(format!("{}VTable", iface.name)); > >- let methods = iface.methods >- .map_err(|reason| format!("Interface {} cannot be implemented in rust \ >- because {} is not supported yet", iface.name, reason))?; >+ let methods = iface.methods.map_err(|reason| { >+ format!( >+ "Interface {} cannot be implemented in rust \ >+ because {} is not supported yet", >+ iface.name, reason >+ ) >+ })?; > > // Generate the vtable for the base interface. > let base_vtable = if let Some(base) = iface.base()? { > let vt = gen_inner_vtable(base)?; > quote!{__base: #vt,} > } else { > quote!{} > }; > > // Include each of the method definitions for this interface. >- let vtable_init = methods.into_iter().map(|method| { >- let name = Ident::from(method.name); >- quote!{ #name : #name , } >- }).collect::<Vec<_>>(); >+ let vtable_init = methods >+ .into_iter() >+ .map(|method| { >+ let name = Ident::from(method.name); >+ quote!{ #name : #name , } >+ }).collect::<Vec<_>>(); > > Ok(quote!(#vtable_ty { > #base_vtable > #(#vtable_init)* > })) > } > > fn gen_root_vtable(name: &Ident, base: &Interface) -> Result<Tokens, Box<Error>> { >@@ -442,23 +463,17 @@ fn gen_casts( > vtable_field: &Ident, > ) -> Result<(Tokens, Tokens), Box<Error>> { > if !seen.insert(iface.name) { > return Ok((quote!{}, quote!{})); > } > > // Generate the cast implementations for the base interfaces. > let (base_qi, base_coerce) = if let Some(base) = iface.base()? { >- gen_casts( >- seen, >- base, >- name, >- coerce_name, >- vtable_field, >- )? >+ gen_casts(seen, base, name, coerce_name, vtable_field)? > } else { > (quote!{}, quote!{}) > }; > > // Add the if statment to QueryInterface for the base class. > let base_name = Ident::from(iface.name); > > let qi = quote! { >@@ -497,25 +512,27 @@ fn gen_casts( > > /// The root xpcom procedural macro definition. > fn xpcom(init: DeriveInput) -> Result<Tokens, Box<Error>> { > if !init.generics.params.is_empty() || !init.generics.where_clause.is_none() { > return Err("Cannot #[derive(xpcom)] on a generic type, due to \ > rust limitations. It is not possible to instantiate \ > a static with a generic type parameter, meaning that \ > generic types cannot have their VTables instantiated \ >- correctly.".into()); >+ correctly." >+ .into()); > } > > let bases = get_bases(&init.attrs)?; > if bases.is_empty() { > return Err("Types with #[derive(xpcom)] must implement at least one \ > interface. Interfaces can be implemented by adding the \ > #[xpimplements(nsIFoo, nsIBar)] attribute to the struct \ >- declaration.".into()); >+ declaration." >+ .into()); > } > > // Determine what reference count type to use, and generate the real struct. > let refcnt_ty = get_refcnt_kind(&init.attrs)?; > let real = gen_real_struct(&init, &bases, refcnt_ty)?; > > let name_init = &init.ident; > let name = &real.ident; >@@ -663,10 +680,11 @@ fn xpcom(init: DeriveInput) -> Result<Tokens, Box<Error>> { > } > } > }) > } > > #[proc_macro_derive(xpcom, attributes(xpimplements, refcnt))] > pub fn xpcom_internal(input: TokenStream) -> TokenStream { > xpcom(parse(input).expect("Invalid derive input")) >- .expect("#[derive(xpcom)] failed").into() >+ .expect("#[derive(xpcom)] failed") >+ .into() > } > </textarea> <iframe id="viewFrame" src="/attachment.cgi?id=9002232" sandbox> <b>You cannot view the attachment while viewing its details because your browser does not support IFRAMEs. <a href="/attachment.cgi?id=9002232">View the attachment on a separate page</a>.</b> </iframe> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH"> <!-- var patchviewerinstalled = 0; var attachment_id = 9002232; if (typeof document.getElementById == "function") { var patchviewerinstalled = 1; document.write('<iframe id="viewDiffFrame" class="bz_default_hidden"><\/iframe>'); document.write('<button type="button" id="viewDiffButton" onclick="viewDiff(attachment_id, patchviewerinstalled);">View Attachment As Diff<\/button>'); document.write('<button type="button" id="viewRawButton" onclick="viewRaw(patchviewerinstalled);" class="bz_default_hidden">View Attachment As Raw<\/button>'); } //--> </script> </div> </div> <div id="attachment_comments_and_flags"> <div id="attachment_flags"> <p><b>Flags:</b></p><span title="Nathan Froyd [:froydnj]">froydnj</span>: feedback+<br> </div> </div> </div> </div> </form> <div id="attachment_actions"><span class="label">Actions:</span> <a href="https://bugzilla-mozilla-org.translate.goog/attachment.cgi?id=9002232&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">View</a> | <a href="https://bugzilla-mozilla-org.translate.goog/attachment.cgi?id=9002232&action=diff&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Diff</a> | <a href="https://bugzilla-mozilla-org.translate.goog/page.cgi?id=splinter.html&ignore&bug=1454764&attachment=9002232&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">Review</a> </div> <div id="attachment_list"> Attachments on <a class="bz_bug_link bz_status_REOPENED" title="REOPENED - [meta] rustfmt mozilla-central" href="https://bugzilla-mozilla-org.translate.goog/show_bug.cgi?id=1454764&_x_tr_sl=pl&_x_tr_tl=iw&_x_tr_hl=en-GB">bug 1454764</a>: <span class="bz_obsolete"> 9002232 </span> </div> <link rel="stylesheet" href="/static/v20241126.1/extensions/FlagTypeComment/web/styles/ftc.css"> <script nonce="aaZdvjPuygMzJJIGV4IzGWzU8PV7JYAiQptetPKwOW0ha3xH" src="/static/v20241126.1/extensions/FlagTypeComment/web/js/ftc.js"></script> </div> </main> </div> <script>function gtElInit() {var lib = new google.translate.TranslateService();lib.translatePage('pl', 'iw', function () {});}</script> <script src="https://translate.google.com/translate_a/element.js?cb=gtElInit&hl=en-GB&client=wt" type="text/javascript"></script> </body> </html>