def __diff_direction(src, patchset, limit = nil)
count = left = left_miss = right = right_miss = 0
string = src.kind_of?(String)
patchset.each do |change|
count += 1
case change
when Diff::LCS::Change
element = string ? src[change.position, 1] : src[change.position]
case change.action
when '-'
if element == change.element
left += 1
else
left_miss += 1
end
when '+'
if element == change.element
right += 1
else
right_miss += 1
end
when '='
if element != change.element
left_miss += 1
right_miss += 1
end
end
when Diff::LCS::ContextChange
case change.action
when '-'
element = string ? src[change.old_position, 1] : src[change.old_position]
if element == change.old_element
left += 1
else
left_miss += 1
end
when '+'
element = string ? src[change.new_position, 1] : src[change.new_position]
if element == change.new_element
right += 1
else
right_miss += 1
end
when '='
le = string ? src[change.old_position, 1] : src[change.old_position]
re = string ? src[change.new_position, 1] : src[change.new_position]
left_miss += 1 if le != change.old_element
right_miss += 1 if re != change.new_element
when '!'
element = string ? src[change.old_position, 1] : src[change.old_position]
if element == change.old_element
left += 1
else
element = string ? src[change.new_position, 1] : src[change.new_position]
if element == change.new_element
right += 1
else
left_miss += 1
right_miss += 1
end
end
end
end
break if (not limit.nil?) && (count > limit)
end
no_left = (left == 0) and (left_miss >= 0)
no_right = (right == 0) and (right_miss >= 0)
case [no_left, no_right]
when [false, true]
return :patch
when [true, false]
return :unpatch
else
raise "The provided patchset does not appear to apply to the provided value as either source or destination value."
end
end