1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
use crate::error::SassResult; use super::Extension; /// An `Extension` created by merging two `Extension`s with the same extender /// and target. /// /// This is used when multiple mandatory extensions exist to ensure that both of /// them are marked as resolved. pub(super) struct MergedExtension; impl MergedExtension { /// Returns an extension that combines `left` and `right`. /// /// Returns an `Err` if `left` and `right` have incompatible media /// contexts. /// /// Returns an `Err` if `left` and `right` don't have the same /// extender and target. pub fn merge(left: Extension, right: Extension) -> SassResult<Extension> { if left.extender != right.extender || left.target != right.target { todo!("we need a span to throw a proper error") // return Err((format!("{} and {} aren't the same extension.", left, right), )) } if left.media_context.is_some() && right.media_context.is_some() && left.media_context != right.media_context { todo!() // throw SassException( // "From ${left.span.message('')}\n" // "You may not @extend the same selector from within different media " // "queries.", // right.span); } if right.is_optional && right.media_context.is_none() { return Ok(left); } if left.is_optional && left.media_context.is_none() { return Ok(right); } Ok(MergedExtension::into_extension(left, right)) } fn into_extension(left: Extension, right: Extension) -> Extension { Extension { extender: left.extender, target: left.target, span: left.span, media_context: match left.media_context { Some(v) => Some(v), None => right.media_context, }, specificity: left.specificity, is_optional: true, is_original: false, left: None, right: None, } // : super(left.extender, left.target, left.extenderSpan, left.span, // left.mediaContext ?? right.mediaContext, // specificity: left.specificity, optional: true); } /// Returns all leaf-node `Extension`s in the tree or `MergedExtension`s. #[allow(dead_code, unused_mut, clippy::unused_self)] pub fn unmerge(mut self) -> Vec<Extension> { todo!() /* Iterable<Extension> unmerge() sync* { if (left is MergedExtension) { yield* (left as MergedExtension).unmerge(); } else { yield left; } if (right is MergedExtension) { yield* (right as MergedExtension).unmerge(); } else { yield right; } } */ } } /* class MergedExtension extends Extension { /// One of the merged extensions. final Extension left; /// The other merged extension. final Extension right; MergedExtension._(this.left, this.right) : super(left.extender, left.target, left.extenderSpan, left.span, left.mediaContext ?? right.mediaContext, specificity: left.specificity, optional: true); } */